\lab{Image Segmentation}{Image Segmentation}

\objective{Graph theory has a variety of applications.
A graph (or network) can be represented in many ways on a computer.
In this lab we study a common matrix representation for graphs and show how certain properties of the matrix representation correspond to inherent properties of the original graph.
% In this lab, we learn to represent a graph as a matrix and to calculate properties of the graph using the matrix representation.
We also introduce tools for working with images in Python, and conclude with an application of using graphs and linear algebra to segment images.
}

\section*{Graphs as Matrices} % ===============================================

A \emph{graph} is a mathematical structure that represents relationships between objects.
Graphs are defined by $G = (V,E)$, where $V$ is a set of \emph{vertices} (or \emph{nodes}) and $E$ is a set of \emph{edges}, each of which connects one node to another.
A graph can be classified in several ways.
\begin{itemize}
    \item The edges of an \emph{undirected} graph are bidirectional: if an edge goes from node $A$ to node $B$, then that same edge also goes from $B$ to $A$.
    For example, the graphs $G_1$ and $G_2$ in Figure \ref{fig:imgseg-example-graphs} are both undirected.
    In a \emph{directed graph}, edges only go one way, usually indicated by an arrow pointing from one node to another.
    In this lab, we focus on undirected graphs.

    \item The edges of a \emph{weighted} graph have a weight assigned to them, such as $G_2$.
    A weighted graph could represent a collection of cities with roads connecting them: each vertex would represent a city, and the edges would represent roads between the cities.
    The length of each road could be the weight of the corresponding edge.
    An \emph{unweighted} graph like $G_1$ does not have weights assigned to its edges, but any unweighted graph can be thought of as a weighted graph by assigning a weight of $1$ to every edge.

    % \item A graph is \emph{simple} if no edge connects a node to itself.
    % The graph in Figure [TODO] is simple, but the graph in Figure [TODO] is not.
\end{itemize}

\begin{figure}[H] % Two graphs.
\captionsetup[subfigure]{justification=centering}
\centering
\begin{subfigure}{.45\textwidth}
    \centering
    \begin{tikzpicture}[auto,node distance=1.5cm,
     thick,main node/.style={circle,draw}]

      \node[main node] (5) [] {6};
      \node[main node] (2) [below right of=5] {3};
      \node[main node] (3) [above right of=5] {4};
      \node[main node] (4) [right of=3] {5};
      \node[main node] (1) [right of=2] {2};
      \node[main node] (0) [below right of=4] {1};

      \foreach \s/\t in {5/3, 3/4, 4/0, 0/1, 1/2, 2/3, 1/4, 5/0} {
       \path[draw] (\s) edge (\t);}
    \end{tikzpicture}
    \caption{$G_1$, an unweighted undirected graph.}
    \label{fig:graphexample-unweighted}
\end{subfigure}
\quad
\begin{subfigure}{.45\textwidth}
    \centering
    \begin{tikzpicture}[auto,node distance=2cm,
    thick,main node/.style={circle,draw}]

    \node[main node] (0) [] {1};
    \node[main node] (1) [below of=0] {2};
    \node[main node] (2) [right of=0] {3};
    \node[main node] (3) [below of=2] {4};
    \node[main node] (4) [right of=2] {5};
    \node[main node] (5) [right of=3] {6};

    \path[draw] (0) edge node [left] {3} (1);
    \path[draw] (2) edge node [left] {1} (3);
    \path[draw] (4) edge node{1} (5);
    \path[draw] (3) edge node{2} (4);
    \path[draw] (3) edge node [below]{.5} (5);
    \end{tikzpicture}
    \caption{$G_2$, a weighted undirected graph.}
    \label{fig:graphexample-weighted}
\end{subfigure}
% \qquad
% \begin{subfigure}{.28\textwidth}
%     \begin{tikzpicture}[->,>=stealth',shorten >=1pt,auto,node distance=1.5cm,
%     thick,main node/.style={circle,draw}]
%
%      \node[main node] (A) [] {A};
%      \node[main node] (B) [below of=A] {B};
%      \node[main node] (C) [right of=A] {C};
%      \node[main node] (D) [below of=C] {D};
%      \node[main node] (E) [right of=C] {E};
%      \node[main node] (F) [right of=D] {F};
%
%      \foreach \s/\t in {A/C, B/A, B/D, C/E, C/F, D/C} {
%       \path[draw] (\s) edge (\t);}
%     \end{tikzpicture}
%     \caption{A directed graph.}
% \end{subfigure}
\caption{}
\label{fig:imgseg-example-graphs}
\end{figure}

\subsection*{Adjacency, Degree, and Laplacian Matrices} % ---------------------

For computation and analysis, graphs are commonly represented by a few special matrices.
For these definitions, let $G$ be a graph with $N$ nodes and let $w_{ij}$ be the weight of the edge connecting node $i$ to node $j$ (if such an edge exists).
%
\begin{enumerate}
\item The \emph{adjacency matrix} of $G$ is the $N\times N$ matrix $A$ with entries
\[
a_{ij} =
\begin{cases}
w_{ij} & \text{if an edge connects node i and node j} \\
0 & \text{otherwise.}
\end{cases}
\]
% If the graph is not simple, there are differing conventions for how to define the diagonal of the adjacency matrix.
The adjacency matrices $A_1$ of $G_1$ and $A_2$ of $G_2$ are
\begin{align*}
A_1 = \left[\begin{array}{cccccc}
0 & 1 & 0 & 0 & 1 & 1\\
1 & 0 & 1 & 0 & 1 & 0\\
0 & 1 & 0 & 1 & 0 & 0\\
0 & 0 & 1 & 0 & 1 & 1\\
1 & 1 & 0 & 1 & 0 & 0\\
1 & 0 & 0 & 1 & 0 & 0
\end{array}\right],
\qquad A_2 =
\left[\begin{array}{cccccc}
0 & 3 & 0 & 0 & 0 & 0\\
3 & 0 & 0 & 0 & 0 & 0\\
0 & 0 & 0 & 1 & 0 & 0\\
0 & 0 & 1 & 0 & 2 & .5\\
0 & 0 & 0 & 2 & 0 & 1\\
0 & 0 & 0 & .5 & 1 & 0
\end{array}\right].
\end{align*}
Notice that these adjacency matrices are symmetric.
This is always the case for undirected graphs since the edges are bidirectional.

\begin{comment} % Paths of a certain length via matrix powers. Not relevant. ==
Raising the adjacency matrix to a power yields some very interesting information.
We can discover the number of paths of length $n$ between two nodes by raising a graph's adjacency matrix to the $n$th power.
For example, by squaring $A$, we can find the number of paths of length two between every pair of nodes.
\begin{lstlisting}
>>> A = np.array([[0,1,0,0,1,0],[1,0,1,0,1,0],
                  [0,1,0,1,0,0],[0,0,1,0,1,1],
                  [1,1,0,1,0,0],[0,0,0,1,0,0]])

>>> np.linalg.matrix_power(A,2)
array([[2, 1, 1, 1, 1, 0],
       [1, 3, 0, 2, 1, 0],
       [1, 0, 2, 0, 2, 1],
       [1, 2, 0, 3, 0, 0],
       [1, 1, 2, 0, 3, 1],
       [0, 0, 1, 0, 1, 1]])
\end{lstlisting}
We can see that no paths of length two exist between node 0 and node 5 because $A^2_{0,5} = 0$.
By calculating $A^6$ we can find the number of paths of length six from node 3 to itself.
\begin{lstlisting}
>>> np.linalg.matrix_power(A, 6)
array([[45, 54, 38, 45, 54, 16],
       [54, 86, 29, 77, 51, 11],
       [38, 29, 55, 15, 70, 27],
       [45, 77, 15, 75, 31,  4],
       [54, 51, 70, 31, 93, 34],
       [16, 11, 27,  4, 34, 14]])
\end{lstlisting}
Therefore there are 75 unique paths of length six from node 3 to itself.
Imagine trying to count all of those paths by hand!
It would be very easy to count incorrectly.
This method makes it very simple to count paths without mistakes.

Adjacency matrices can also be composed of \li{True} and \li{False} values.
In this case, the $n$th power of such a matrix (using boolean arithmetic)
is again a matrix of
boolean values which simply indicate whether there exists a path of length $n$ between the given pair of nodes, rather than indicating the number of such
paths.

\begin{problem}
Let the following matrix represent a directed graph
\[
\begin{array}{ccccccc}
0 & 0 & 1 & 0 & 1 & 0 & 1 \\
1 & 0 & 0 & 0 & 0 & 1 & 0 \\
0 & 0 & 0 & 0 & 0 & 1 & 0 \\
1 & 0 & 0 & 0 & 1 & 0 & 0 \\
0 & 0 & 0 & 1 & 0 & 0 & 0 \\
0 & 0 & 1 & 0 & 0 & 0 & 1 \\
0 & 1 & 0 & 0 & 0 & 0 & 0
\end{array}\right]
\]
Between which pair of nodes does there exist the greatest number of paths
of length five?
From which node to which node is there no path of length seven?
\end{problem}
\end{comment} % ===============================================================

\item The \emph{degree matrix} of $G$ is the $N \times N$ diagonal matrix $D$ whose $i$th diagonal entry is
\begin{equation}
d_{ii} = \sum_{j=1}^N w_{ij}.
\label{eq:degree-matrix-formula}
\end{equation}
%For a directed graph, each node has an \emph{out-degree} (the number of edges directed away from a node) and an \emph{in-degree} (the number edges directed toward a node).
The degree matrices $D_1$ of $G_1$ and $D_2$ of $G_2$ are
\begin{align*}
D_1 = \left[\begin{array}{cccccc}
3 & 0 & 0 & 0 & 0 & 0\\
0 & 3 & 0 & 0 & 0 & 0\\
0 & 0 & 2 & 0 & 0 & 0\\
0 & 0 & 0 & 3 & 0 & 0\\
0 & 0 & 0 & 0 & 3 & 0\\
0 & 0 & 0 & 0 & 0 & 2
\end{array}\right],
\qquad D_2 =
\left[\begin{array}{cccccc}
3 & 0 & 0 & 0 & 0 & 0\\
0 & 3 & 0 & 0 & 0 & 0\\
0 & 0 & 1 & 0 & 0 & 0\\
0 & 0 & 0 & 3.5 & 0 & 0\\
0 & 0 & 0 & 0 & 3 & 0\\
0 & 0 & 0 & 0 & 0 & 1.5
\end{array}\right].
\end{align*}
The $i$th diagonal entry of $D$ is called the \emph{degree} of node $i$, the sum of the weights of the edges leaving node $i$.

\item The \emph{Laplacian matrix} of $G$ is the $N\times N$ matrix $L$ defined as
\begin{equation}
L = D - A,
\label{eq:laplacian-matrix-formula}
\end{equation}
where $D$ is the degree matrix of $G$ and $A$ is the adjacency matrix of $G$.
For $G_1$ and $G_2$, the Laplacian matrices $L_1$ and $L_2$ are
\begin{align*}
L_1 =\left[\begin{array}{rrrrrr}
3 & -1 & 0 & 0 & -1 & -1\\
-1 & 3 & -1 & 0 & -1 & 0\\
0 & -1 & 2 & -1 & 0 & 0\\
0 & 0 & -1 & 3 & -1 & -1\\
-1 & -1 & 0 & -1 & 3& 0\\
-1 & 0 & 0 & -1 & 0 & 2
\end{array}\right],
\qquad L_2 =
 \left[\begin{array}{rrrrrr}
3 & -3 & 0 & 0 & 0 & 0\\
-3 & 3 & 0 & 0 & 0 & 0\\
0 & 0 & 1 & -1 & 0 & 0\\
0 & 0 & -1 & 3.5 & -2 & -.5\\
0 & 0 & 0 & -2 & 3 & -1\\
0 & 0 & 0 &- .5 & -1 & 1.5
\end{array}\right].
\end{align*}
\end{enumerate}

\begin{problem}
Write a function that accepts the adjacency matrix $A$ of a graph $G$.
Use (\ref{eq:degree-matrix-formula}) and (\ref{eq:laplacian-matrix-formula}) to compute the Laplacian matrix $L$ of $G$.
\\(Hint: The diagonal entries of $D$ can be computed in one line by summing $A$ over an axis.)

Test your function on the graphs $G_1$ and $G_2$ from Figure \ref{fig:imgseg-example-graphs} and validate your results with \li{scipy.sparse.csgraph.laplacian()}.
\label{prob:imgseg-laplacian}
\end{problem}

\subsection*{Connectivity} % --------------------------------------------------

A \emph{connected graph} is a graph where every vertex is connected to every other vertex by at least one path.
For example, $G_1$ is connected, whereas $G_2$ is not because there is no path from node $1$ (or node $2$) to node $3$ (or nodes $4$, $5$, or $6$).
The na\"ive brute-force algorithm for determining if a graph is connected is to check that there is a path from each edge to every other edge.
While this may work for very small graphs, most interesting graphs have thousands of vertices, and for such graphs this approach is prohibitively expensive.
Luckily, an interesting result from algebraic graph theory relates the connectivity of a graph to its Laplacian matrix.

If $L$ is the Laplacian matrix of a graph, then the definition of $D$ and the construction $L = D - A$ guarantees that the rows (and columns) of $L$ must each sum to $0$.
Therefore $L$ cannot have full rank, so $\lambda = 0$ must be an eigenvalue of $L$.
Furthermore, if $L$ represents a graph that is \textbf{not} connected, more than one of the eigenvalues of $L$ must be zero.
To see this, let $J \subset \{1,2,\ldots,N\}$ such that the vertices $\{v_j\}_{j \in J}$ form a connected component of the graph, meaning that there is a path between each pair of vertices in the set.
Next, let $\x$ be the vector with entries
 \[
x_k = \begin{cases}
1, & k \in J    \\
0, & k \not\in J.
\end{cases}
  \]
Then $\x$ is an eigenvector of $L$ corresponding to the eigenvalue $\lambda = 0$.
% In other words, for each connected component, $0$ appears at least once as an eigenvalue.

For example, the example graph $G_2$ has two connected components.
\begin{enumerate}
\item $J_1 = \{1,2\}$ so that $\x_1 = [1, 1, 0, 0, 0, 0]\trp$.
Then
\[
L_2\x_1 =
\left[\begin{array}{rrrrrr}
3 & -3 & 0 & 0 & 0 & 0\\
-3 & 3 & 0 & 0 & 0 & 0\\
0 & 0 & 1 & -1 & 0 & 0\\
0 & 0 & -1 & 3.5 & -2 & -.5\\
0 & 0 & 0 & -2 & 3 & -1\\
0 & 0 & 0 &- .5 & -1 & 1.5
\end{array}\right]
\left[\begin{array}{c}
1 \\ 1 \\ 0 \\ 0 \\ 0 \\ 0
\end{array}\right]
=
\left[\begin{array}{c}
0 \\ 0 \\ 0 \\ 0 \\ 0 \\ 0
\end{array}\right]
= \0.
\]

\item $J_2 = \{3,4,5,6\}$ and hence $\x_2 = [0, 0, 1, 1, 1, 1]\trp$.
Then
\[
L_2\x_2 =
\left[\begin{array}{rrrrrr}
3 & -3 & 0 & 0 & 0 & 0\\
-3 & 3 & 0 & 0 & 0 & 0\\
0 & 0 & 1 & -1 & 0 & 0\\
0 & 0 & -1 & 3.5 & -2 & -.5\\
0 & 0 & 0 & -2 & 3 & -1\\
0 & 0 & 0 &- .5 & -1 & 1.5
\end{array}\right]
\left[\begin{array}{c}
0 \\ 0 \\ 1 \\ 1 \\ 1 \\ 1
\end{array}\right]
=
\left[\begin{array}{c}
0 \\ 0 \\ 0 \\ 0 \\ 0 \\ 0
\end{array}\right]
= \0.
\]
\end{enumerate}

In fact, it can be shown that the number of zero eigenvalues of the Laplacian exactly equals the number of connected components.
This makes calculating how many connected components are in a graph only as hard as calculating the eigenvalues of its Laplacian.

A Laplacian matrix $L$ is always a positive semi-definite matrix when all weights in the graph are positive, meaning that its eigenvalues are each nonnegative.
The second smallest eigenvalue of $L$ is called the \emph{algebraic connectivity} of the graph.
It is clearly $0$ for non-connected graphs, but for a connected graph, the algebraic connectivity provides useful information about its sparsity or ``connectedness.''
A higher algebraic connectivity indicates that the graph is more strongly connected.

\begin{problem}
Write a function that accepts the adjacency matrix $A$ of a graph $G$ and a small tolerance value \li{tol}.
Compute the number of connected components in $G$ and its algebraic connectivity.
Consider all eigenvalues that are less than the given \li{tol} to be zero.

Use \li{scipy.linalg.eig()} or \li{scipy.linalg.eigvals()} to compute the eigenvalues of the Laplacian matrix.
These functions return complex eigenvalues (with negligible imaginary parts); use \li{np.real()} to extract the real parts.
\end{problem}

\begin{comment} % Likelihood of connectedness.
\begin{problem}
% Used to be part of the previous problem.
% Rmoved because these is no great way to evaluate it.
The folowing function creates a random symmetric matrix of Boolean values with sparsity determined by the input \li{c}.
\begin{lstlisting}
def sparse_generator(n, c):
    """Return a symmetric nxn matrix with sparsity determined by c."""
    A = np.random.rand(n**2).reshape((n, n))
    A = ( A > c**(.5) )
    return A.T @ A
\end{lstlisting}

Test your function from the previous problem on matrices created by \li{sparse_generator()} with inputs $n = 10, 100$ and $c = .25, .5, .95$.
What do you notice about the likelihood that a random graph is connected?
\end{problem}
\end{comment}

\section*{Images as Matrices} % ===============================================

Computer images are stored as arrays of integers that indicate pixel values.
Most $m\times n$ grayscale (black and white) images are stored in Python as a $m\times n$ NumPy arrays, while most $m\times n$ color images are stored as $3$-dimensional $m\times n \times 3$ arrays.
Color image arrays can be thought of as a stack of three $m\times n$ arrays, one each for red, green, and blue values.
% \footnote{See \url{http://scikit-image.org/docs/dev/user_guide/numpy_images.html\#coordinate-conventions} for other conventions.}
The datatype for an image array is \li{np.uint8}, unsigned 8-bit integers that range from $0$ to $255$.
A $0$ indicates a black pixel while a $255$ indicates a white pixel.

Use \li{imageio.imread()} to read an image from a file and \li{imageio.imwrite()} to save an image.
Matplotlib's \li{plt.imshow()} displays an image array, but it displays arrays of floats between $0$ and $1$ more cleanly than arrays of 8-bit integers.
Therefore it is customary to scale the array by dividing each entry by $255$ before processing or showing the image.
In this case, a $0$ still indicates a black pixel, but now a $1$ indicates pure white.

\begin{lstlisting}
>>> from imageio import imread
>>> from matplotlib import pyplot as plt

>>> image = imread("dream.png")     # Read a (very) small image.
>>> print(image.shape)              # Since the array is 3-dimensional,
(48, 48, 3)                         # this is a color image.

# The image is read in as integers from 0 to 255.
>>> print(image.<<min>>(), image.<<max>>(), image.dtype)
0 254 uint8

# Scale the image to floats between 0 and 1 for Matplotlib.
>>> scaled = image / 255.
>>> print(scaled.<<min>>(), scaled.<<max>>(), scaled.dtype)
0.0 0.996078431373 float64

# Display the scaled image.
>>> plt.imshow(scaled)
>>> plt.axis("off")
\end{lstlisting}

A color image can be converted to grayscale by averaging the RGB values of each pixel, resulting in a 2-D array called the \emph{brightness} of the image.
To properly display a grayscale image, specify the keyword argument \li{cmap="gray"} in \li{plt.imshow()}.

\begin{lstlisting}
# Average the RGB values of a colored image to obtain a grayscale image.
>>> brightness = scaled.mean(axis=2)        # Average over the last axis.
>>> print(brightness.shape)                 # Note that the array is now 2-D.
(48, 48)

# Display the image in gray.
>>> plt.imshow(brightness, cmap="gray")
>>> plt.axis("off")
\end{lstlisting}

Finally, it is often important in applications to flatten an image matrix into a large 1-D array.
Use \li{np.ravel()} to convert a $m\times n$ array into a 1-D array with $mn$ entries.

\begin{lstlisting}
>>> import numpy as np
>>> A = np.random.randint(0, 10, (3,4))
>>> print(A)
[[4 4 7 7]
 [8 1 2 0]
 [7 0 0 9]]

# Unravel the 2-D array (by rows) into a 1-D array.
>>> np.ravel(A)
array([4, 4, 7, 7, 8, 1, 2, 0, 7, 0, 0, 9])

# Unravel a grayscale image into a 1-D array and check its size.
>>> M,N = brightness.shape
>>> flat_brightness = np.ravel(brightness)
>>> M*N == flat_brightness.size
<<True>>
>>> print(flat_brightness.shape)
(2304,)
\end{lstlisting}

\begin{problem} % Read and display an image.
Define a class called \li{ImageSegmenter}.
\begin{enumerate}
    \item Write the constructor so that it accepts the name of an image file.
    Read the image, scale it so that it contains floats between $0$ and $1$, then store it as an attribute.
    If the image is in color, compute its brightness matrix by averaging the RGB values at each pixel (if it is a grayscale image, the image array itself is the brightness matrix).
    Flatten the brightness matrix into a 1-D array and store it as an attribute.

    \item Write a method called \li{show_original()} that displays the original image.
    If the original image is grayscale, remember to use \li{cmap="gray"} as part of \li{plt.imshow()}.
\end{enumerate}
\end{problem}

\begin{warn} % Do not use plt.imread() because it is inconsistent.
Matplotlib's \li{plt.imread()} also reads image files.
However, this function automatically scales PNG image entries to floats between $0$ and $1$, but it still reads non-PNG image entries as 8-bit integers.
To avoid this inconsistent behavior, always use \li{imageio.imread()} to read images and divide by $255$ when scaling is desired.
\end{warn}

\section*{Graph-based Image Segmentation} % ===================================

\emph{Image segmentation} is the process of finding natural boundaries in an image and partitioning the image along those boundaries (see Figure \ref{fig:imgseg-segmentation-example}).
Though humans can easily pick out portions of an image that ``belong together,'' it takes quite a bit of work to teach a computer to recognize boundaries and sections in an image.
However, segmenting an image often makes it easier to analyze, so image segmentation is ongoing area of research in computer vision and image processing.

\begin{figure}[H] % Segmentation example.
    \centering
    \begin{subfigure}{.32\textwidth}
        \includegraphics[width=\textwidth]{figures/dream.pdf}
    \end{subfigure}
    %
    \begin{subfigure}{.32\textwidth}
        \includegraphics[width=\textwidth]{figures/dream_pos.pdf}
    \end{subfigure}
    %
    \begin{subfigure}{.32\textwidth}
        \includegraphics[width=\textwidth]{figures/dream_neg.pdf}
    \end{subfigure}
\caption{The image \texttt{dream.png} and its segments.}
\label{fig:imgseg-segmentation-example}
\end{figure}

There are many ways to approach image segmentation.
The following algorithm, developed by Jianbo Shi and Jitendra Malik in 2000 \cite{Shi2000}, converts the image to a graph and ``cuts'' it into two connected components.

\subsection*{Constructing the Image Graph} % ----------------------------------

Let $G$ be a graph whose vertices are the $mn$ pixels of an $m\times n$ image (either grayscale or color).
% That is, vertex $i$ in $G$ represents the pixel at index $i$ when the image is flattened to a vector with $mn$ entries.
Each vertex $i$ has a brightness $B(i)$, the grayscale or average RGB value of the pixel, as well as a coordinate location $X(i)$, the indices of the pixel in the original image array.

Define $w_{ij}$, the weight of the edge between pixels $i$ and $j$, by
\begin{equation}
\label{eq:imgseg-edge-weight}
w_{ij} = \begin{cases}
\exp\left(-\frac{|B(i) - B(j)|}{\sigma_B^2}-\frac{\|X(i) - X(j)\|}{\sigma_X^2}\right) & \text{if}\ \|X(i) - X(j)\| < r \\ 0 & \text{otherwise,}
\end{cases}
\end{equation}
where $r$, $\sigma_B^2$ and $\sigma_X^2$ are constants for tuning the algorithm.
In this context, $\|\cdot\|$ is the standard \emph{euclidean norm}, meaning that $\|X(i) - X(j)\|$ is the physical distance between vertices $i$ and $j$, measured in pixels.

With this definition for $w_{ij}$, pixels that are farther apart than the radius $r$ are not connected at all in $G$.
Pixels within $r$ of each other are more strongly connected if they are similar in brightness and close together (the value in the exponential is negative but close to zero).
On the other hand, highly contrasting pixels where $|B(i) - B(j)|$ is large have weaker connections (the value in the exponential is highly negative).

\begin{figure}[H] % The adjacency matrix. DO NOT DELETE. EVER.
\begin{tikzpicture}[dot/.style={circle,fill=black,minimum
    size=4pt,inner sep=0pt,outer sep=-1pt}, >=stealth]
%scale=.85, transform shape,

%image
\draw[step=.75,thick](2.999,0)grid(6,3);
%numbers 1-16
\foreach \x in {0,1,2,3}
    \foreach \y in {4}
        \node[draw=none, anchor=south west]at(\x*.75+3.25, \y-1.4){\x};
\foreach \x [evaluate=\x as \r using int(\x+4)]in {0,1,2,3}
    \foreach \y in {3}
        \node[draw=none, anchor=south west]at(\x*.75+3.25, \y-1.2){\r};
\foreach \x [evaluate=\x as \r using int(\x+8)] in {0,1,2,3}
    \foreach \y in {2}
        \node[draw=none, anchor=south west]at(\x*.75+3.25, \y-.95){\r};
\foreach \x [evaluate=\x as \r using int(\x+12)] in {0,1,2,3}
    \foreach \y in {1}
        \node[draw=none, anchor=south west]at(\x*.75+3.25, \y-.7){\r};

\node[draw=none](image)at(4.5, -.5){\emph{image}};
\node[draw=none](flattened)at(7.25,-3){\emph{flattened image}};
\node[draw=none](adjacency)at(12,-3){\emph{adjacency matrix} $A$};

%dots within grid
\foreach \x in {1,2,3,4}
    \foreach \y in {1,2,3,4}
        \node[draw, dot]at(\x*.75+2.6,\y*.75-.4){};

%color fill
\foreach \x/\y in {2/3.75, 1.25/3, 2/3, 2.75/3, 2/2.25} {\node[draw, minimum
    size=.75cm, fill=green!30!black, fill opacity=.25]at(\x+2.118,\y-1.118){};}

%circle in image
\node[draw, circle, minimum size=2cm,thick](circle)at(4.13,1.86){};

%flattened image
\draw[step=.5, thick](6.999,-2.5)grid(7.5,5.5);
\foreach \x in {7}
    \foreach \y in {0,...,15}
        \node[draw=none]at(\x+.25,\y*-.5+5.25){\y};

\draw[->,thick](6.1, 1.5)--(6.9,1.5);

%adjancey matrix
\draw[step=.5](7.9999,-2.5)grid(16,5.5);
%\draw[step=2,thick](7.999,-2.5)grid(16,5.5);

%outside labels
\foreach \x in {0,4,8,12} {\node[draw=none]at(\x*.5+8.25,5.8){\x};}
\foreach \y in {0,4,8,12}{\node[draw=none]at(16.3,\y*-.5+5.3){\y};}

%shading of boxes
\foreach \x/\y in {8.5/5.5, 9/5.5, 8.5/5, 9/5, 9.5/5,9/4.5,9.5/4.5,10/4.5,
    9.5/4, 10/4, 10.5/5.5, 11/5,11.5/4.5, 12/4, 12.5/3.5,
    13.5/2.5, 14/2, 14.5/1.5, 15/1, 15.5/.5,16/0, 10.5/3.5, 11/3.5, 11/2.5,
    11.5/2.5,12/2.5, 11.5/2,12/2, 12.5/1.5, 13/1.5, 12.5/1, 13/1,
    13.5/1,13/.5,13.5/.5,14/.5, 13.5/0,14/0, 14.5/-.5,15/-.5,14.5/-1,
    15/-1,15.5/-1, 15/-1.5, 15.5/-1.5, 16/-1.5, 15.5/-2, 16/-2, 8.5/3.5,
    9.5/2.5,10/2,10.5/1.5,11/1,11.5/.5,12/0, 12.5/-.5, 13/-1, 13.5/-1.5, 14/-2}
    {\node[draw, minimum size=.5cm, fill=black, fill opacity=.25]
    at(\x-.25,\y-.25){};}

%green shaded boxes
\foreach \x/\y in {9/3,11/3, 11.5/3, 10.5/3, 13/3} {\node
    [draw, minimum size=.5cm, fill=shadecolor]
    at(\x-.25,\y-.25){};}

\node[draw=none]at(8.75,2.75){1};
\node[draw=none]at(10.25,2.75){4};
\node[draw=none]at(10.75,2.75){5};
\node[draw=none]at(11.25,2.75){6};
\node[draw=none]at(12.75,2.75){9};
\end{tikzpicture}

\caption{The grid on the left represents a $4\times4$ ($m \times n$) image with $16$ pixels.
On the right is the corresponding $16 \times 16$ ($mn \times mn$) adjacency matrix with all nonzero entries shaded.
For example, in row $5$, entries $1$, $4$, $5$, $6$, and $9$ are nonzero because those pixels are within radius $r=1.2$ of pixel $5$.}
\label{fig:imgseg-adjacency-tikz}
\end{figure}

Since there are $mn$ total pixels, the adjacency matrix $A$ of $G$ with entries $w_{ij}$ is $mn\times mn$.
With a relatively small radius $r$, $A$ is relatively sparse, and should therefore be constructed and stored as a sparse matrix.
The degree matrix $D$ is diagonal, so it can be stored as a regular 1-dimensional NumPy array.
The procedure for constructing these matrices can be summarized in just a few steps.
\begin{enumerate}
    \item Initialize $A$ as a sparse $mn\times mn$ matrix and $D$ as a vector with $mn$ entries.
    \item For each vertex $i$ ($i=0,1,\ldots,mn-1$),
    \begin{enumerate}
        \item Find the set of all vertices $J_i$ such that $\|X(i) - X(j)\| < r$ for each $j\in J_i$.
        For example, in Figure \ref{fig:imgseg-adjacency-tikz} $i=5$ and $J_i = \{1,4,5,6,9\}$.
        \label{step:imgseg-neighborhood}
        \item Calculate the weights $w_{ij}$ for each $j\in J_i$ according to (\ref{eq:imgseg-edge-weight}) and store them in $A$.
        \item Set the $i$th element of $D$ to be the sum of the weights, $d_i = \sum_{j\in J_i}w_{ij}$.
    \end{enumerate}
\end{enumerate}

The most difficult part to implement efficiently is step \ref{step:imgseg-neighborhood}, computing the neighborhood $J_i$ of the current pixel $i$.
However, the computation only requires knowing the current index $i$, the radius $r$, and the height and width $m$ and $n$ of the original image.
The following function takes advantage of this fact and returns (as NumPy arrays) both $J_i$ and the distances $\|X(i) - X(j)\|$ for each $j\in J_i$.

% get_neighbors() helper function.
\begin{lstlisting}
def get_neighbors(index, radius, height, width):
    """Calculate the flattened indices of the pixels that are within the given
    distance of a central pixel, and their distances from the central pixel.

    Parameters:
        index (int): The index of a central pixel in a flattened image array
            with original shape (radius, height).
        radius (float): Radius of the neighborhood around the central pixel.
        height (int): The height of the original image in pixels.
        width (int): The width of the original image in pixels.

    Returns:
        (1-D ndarray): the indices of the pixels that are within the specified
            radius of the central pixel, with respect to the flattened image.
        (1-D ndarray): the euclidean distances from the neighborhood pixels to
            the central pixel.
    """
    # Calculate the original 2-D coordinates of the central pixel.
    row, col = index // width, index % width

    # Get a grid of possible candidates that are close to the central pixel.
    r = int(radius)
    x = np.arange(max(col - r, 0), min(col + r + 1, width))
    y = np.arange(max(row - r, 0), min(row + r + 1, height))
    X, Y = np.meshgrid(x, y)

    # Determine which candidates are within the given radius of the pixel.
    R = np.sqrt(((X - col)**2 + (Y - row)**2))
    mask = R < radius
    return (X[mask] + Y[mask]*width).astype(np.<<int>>), R[mask]
\end{lstlisting}

To see how this works, consider Figure \ref{fig:imgseg-adjacency-tikz} where the original image is $4\times 4$ and the goal is to compute the neighborhood of the pixel $i = 5$.

\begin{lstlisting}
# Compute the neighbors and corresponding distances from the figure.
>>> neighbors_1, distances_1 = get_neighbors(5, 1.2, 4, 4)
>>> print(neighbors_1, distances_1, sep='\n')
[1 4 5 6 9]
[ 1.  1.  0.  1.  1.]

# Increasing the radius from 1.2 to 1.5 results in more neighbors.
>>> neighbors_2, distances_2 = get_neighbors(5, 1.5, 4, 4)
>>> print(neighbors_2, distances_2, sep='\n')
[ 0  1  2  4  5  6  8  9 10]
[ 1.41421356  1.          1.41421356  1.          0.          1.
  1.41421356  1.          1.41421356]
\end{lstlisting}

\begin{problem}
Write a method for the \li{ImageSegmenter} class that accepts floats $r$ defaulting to $5$, $\sigma_B^2$ defaulting to $.02$, and $\sigma_X^2$ defaulting to $3$.
Compute the adjacency matrix $A$ and the degree matrix $D$ according to the weights specified in (\ref{eq:imgseg-edge-weight}).

Initialize $A$ as a \li{scipy.sparse.lil_matrix}, which is optimized for incremental construction.
Fill in the nonzero elements of $A$ one row at a time.
Use \li{get_neighbors()} at each step to help compute the weights.
\\(Hint: Try to compute and store an entire row of weights at a time.
What does the command \li{A[5, np.array([1, 4, 5, 6, 9])] = weights} do?)

Finally, convert $A$ to a \li{scipy.sparse.csc_matrix}, which is faster for computations.
Then return $A$ and $D$.

Use \li{blue_heart.png} to test $A$ and $D$, saved as \texttt{HeartMatrixA.npz} and \texttt{HeartMatrixD.npy} datafiles.
\label{prob:imgseg-compute-adjacency}
\end{problem}

\subsection*{Segmenting the Graph} % ------------------------------------------

With an image represented as a graph $G$, the goal is to now split $G$ into two distinct connected components by removing edges from the existing graph.
This is called \emph{cutting} $G$, and the set of edges that are removed is called the \emph{cut}.
The cut with the least weight will best segment the image.

Let $D$ be the degree matrix and $L$ be the Laplacian matrix of $G$.
Shi and Malik \cite{Shi2000} proved that the eigenvector corresponding to the second smallest\footnote{Both $D$ and $L$ are symmetric matrices, so all eigenvalues of $D^{-1/2}LD^{-1/2}$ are real, and therefore ``the second smallest one'' is well-defined.} eigenvalue of $D^{-1/2}LD^{-1/2}$ can be used to minimize the cut: the indices of its positive entries are the indices of the pixels in the flattened image which belong to one segment, and the indices of its negative entries are the indices of the pixels which belong to the other segment.
In this context $D^{-1/2}$ refers to element-wise exponentiation, so the $(i,j)$th entry of $D^{-1/2}$ is $1/\sqrt{d_{ij}}$.

Because $A$ is $mn\times mn$, the desired eigenvector has $mn$ entries.
Reshaping the eigenvector to be $m \times n$ allows it to align with the original image.
Use the reshaped eigenvector to create a boolean mask that indexes one of the segments.
That is, construct a $m\times n$ array where the entries belonging to one segment are \li{True} and the other entries are \li{False}.

\begin{lstlisting}
>>> x = np.arange(-5,5).reshape((5,2)).T
>>> print(x)
[[-5 -3 -1  1  3]
 [-4 -2  0  2  4]]

# Construct a boolean mask of x describing which entries of x are positive.
>>> mask = x > 0
>>> print(mask)
<<[[False False False  True  True]
 [False False False  True  True]]>>

# Use the mask to zero out all of the nonpositive entries of x.
>>> x * mask
array([[0, 0, 0, 1, 3],
       [0, 0, 0, 2, 4]])
\end{lstlisting}

\begin{problem}
Write a method for the \li{ImageSegmenter} class that accepts an adjacency matrix $A$ as a \li{scipy.sparse.csc_matrix} and a degree matrix $D$ as a 1-D NumPy array.
Construct an $m\times n$ boolean mask describing the segments of the image.
\begin{enumerate}
    \item Compute the Laplacian $L$ with \li{scipy.sparse.csgraph.laplacian()} or by converting $D$ to a sparse diagonal matrix and computing $L = D - A$ (do not use your function from Problem \ref{prob:imgseg-laplacian} unless it works correctly and efficiently for sparse matrices).

    \item Construct $D^{-1/2}$ as a sparse diagonal matrix using $D$ and \li{scipy.sparse.diags()}, then compute $D^{-1/2}LD^{-1/2}$.
    Use \li{@} or the \li{dot()} method of the sparse matrix for the matrix multiplication, \textbf{not} \li{np.dot()}.

    \item Use \li{scipy.sparse.linalg.eigsh()} to compute the eigenvector corresponding to the second-smallest eigenvalue of $D^{-1/2} L D^{-1/2}$.
    Set the keyword arguments \li{which="SM"} and \li{k=2} to compute only the two smallest eigenvalues and their eigenvectors.

    \item Reshape the eigenvector as a $m\times n$ matrix and use this matrix to construct the desired boolean mask.
    Return the mask.
\end{enumerate}
\label{prob:imgseg-compute-mask}
\end{problem}

Multiplying the boolean mask component-wise by the original image array produces the \emph{positive segment}, a copy of the original image where the entries that aren't in the segment are set to $0$.
Computing the \emph{negative segment} requires inverting the boolean mask, then multiplying the inverted mask with the original image array.
Finally, if the original image is a $m \times n \times 3$ color image, the mask must be stacked into a $m \times n \times 3$ array to facilitate entry-wise multiplication.

\begin{lstlisting}
>>> mask = np.arange(-5,5).reshape((5,2)).T > 0
>>> print(mask)
<<[[False False False  True  True]
 [False False False  True  True]]>>

# The mask can be negated with the tilde operator ~.
>>> print(~mask)
<<[[ True  True  True False False]
 [ True  True  True False False]]>>

# Stack a mask into a 3-D array with np.dstack().
>>> print(mask.shape, np.dstack((mask, mask, mask)).shape)
(2, 5) (2, 5, 3)
\end{lstlisting}

\begin{problem}
Write a method for the \li{ImageSegmenter} class that accepts floats $r$, $\sigma_B^2$, and $\sigma_X^2$, with the same defaults as in Problem \ref{prob:imgseg-compute-adjacency}.
Call your methods from Problems \ref{prob:imgseg-compute-adjacency} and \ref{prob:imgseg-compute-mask} to obtain the segmentation mask.
Plot the original image, the positive segment, and the negative segment side-by-side in subplots.
Your method should work for grayscale or color images.

Use \texttt{dream.png} as a test file and compare your results to Figure \ref{fig:imgseg-segmentation-example}.
\end{problem}

\begin{comment} % TODO

\newpage

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

\subsection*{Products of Adjacency Matrices} % --------------------------------

\subsection*{Other Methods for Image Segmentation} % --------------------------

\end{comment}


\documentclass{article}
\usepackage{amsmath}
\usepackage{cite}
\title{Notes on How Combinatorics Improves Tree Enumeration}
\begin{document}
\maketitle

\section{Graph Coloring Counting}

\noindent Definition

\noindent The chromatic function is a polynomial proved by deletion/contraction
induction.

\noindent Combinatorics gives us counting interpretations of the \textit{coefficients}
of the chromatic polynomial.  So the chromatic polynomial is a case of
a \textbf{generating function} whose \textit{values} $\chi(G,n)$ are interesting.

\section{Tutte Polynomial--Delection/Contraction}

\[
T(G,x,y) = \left\{ \begin{array}{ll}
  x^{\text{\# isthmuses}}y^{\text{\# loops}} & \text{if }G\text{ contains loops or isthmuses only,}\\
  T(G/e,x,y)+T(G\setminus e,x,y) & \text{if }e\in E(G)
     \text{ is neither a loop nor an isthmus.}
  \end{array}
  \right\}
\]

Chromatic specialization:

\[
\chi(G,n) = (-1)^{|V(G)|-k(G)}n^{k(G)}T(G,(1-n),0)
\]

Tutte's activities expansion:
\[
T(G,x,y) = \sum_{\text{Bases A}}x^{|IA(A)|}y^{|EA(A)|}
\]

\section{Inclusion/Exclusion and Whitney's Solution}

\[
\chi(G,n) = \sum_{k=0}^{k=|E|}(-1)^k \text{\# }n\text{ colorings violating at least }
k\text{ edges}
\]

\[
\chi(G,n) = \sum_{A\subseteq E}(-1)^{|A|}
(\text{\# }n\text{ colorings violating at least the edges }A)
\]

\[
\chi(G,n) = \sum_{A\subseteq E}(-1)^{|A|}
n^{|V(G/A)|} = n^{|V(G)|} + (\text{polynomial in } n \text{ of degree } < |V(G)|)
\]
which establishes that $\chi$ is a polynomial function.

Whitney\cite{WhitLogExpMath} observed that
many pairs of terms, those for which $A$ contains at least
one \textbf{broken circuit}, may be cancelled.

If $A$ contains circuit $C$ and $e\in C$, then $V(G/A) = V(G/(A\setminus e))$

So Whitney's idea was to impose a linear order on a subset $\mathcal{B}$
of the $A$'s occurring
in the sum so that a pairing $\{A,A'\}$ of the members of $\mathcal{B}$
is defined for which $\{A,A'\}=\{A'\cup e, A'\}$, $e\not\in A'$ for some $e$
and $k(G/A) = k(G/(A\setminus e))$.  Two benefits result:
\begin{enumerate}
\item Many of the terms may be omitted.
\item The subsets $A$ for the remaining terms all have a simple form with the
result $|V(G/A)| = |V(G)| - |A| $.

\section{Posets, Inclusion/Exclusion and the Mobius Function}

The M\"{o}bius function emerges when the principle of inclusion/exclusion is
applied to enumerations on elements of general posets.

(I'll try a tutorial that directly relates the M\"{o}bius defining recurrance to
solving $g(x) = \sum_{z\le x}f(z)$ for $f()$.)

(The resulting mathematical abstraction is Stanley's
\textbf{Incidence Algebra} of a poset\cite{StanleyEC1}.)

Stanley: ``Hence M\"{o}bius inversion results in a simplification
of Inclusion-Exclusion under appropriate circumstances. However, we shall also see that
the applications of M\"{o}bius inversion are much
further-reaching than as a generalization of
Inclusion-Exclusion.'' \cite[ch.~3]{StanleyEC1}.

\subsection{Characteristic Polynomial}

\[
\chi(G,n) = \sum_{\textbf{0}\le z\le \textbf{1}}\mu(\textbf{0}, z)n^{|V(G)|-\text{rank}(z)}
\]
where the sum is over the geometric lattice of flats (closed subsets of edges)
in the graphic matroid of $G$.

Proof.  Each flat $z$ corresponds to a graph $G/A$ obtained by
contracting some
subset $A$ of edges and then removing the loops.
(The edges in the flat are $A$ plus those removed loops.)
The number of unrestricted colorings of $G/A$ is $n^{V(G/A)-\text{rank}(z)}$.
The number of legal colorings of each $G/A'$ is of course $\chi(G/A',n)$.
Each unrestricted coloring of $G/A$ corresponds to a unique legal coloring of
the graph obtained from $G/A$ by contracting the violated edges of $G/A$.
Therefore
\[
n^{V(G/A)-\text{rank}(z)} = \sum_{z'\ge z}\chi(G/A',n).
\]
The formula for $\chi(G,n)$ is the result of M\"{o}bius inversion because
$G$ (with no edges contracted) corresponds to the bottom flat $\textbf{0}$.

Factoring out $n^{k(G)}$ gives us a polynomial function that generalizes
to all finite lattices.
$\chi(G,n)=n^{k(G)}\text{char}(\mathcal{L},n)$ where

\[
\text{char}(\mathcal{L},n) =
\sum_{z\in\mathcal{L}}\mu(z,\mathbf{1})n^{\text{rank}(\mathbf{1}) - \text{rank}(z)}.
\]

\section{Broken Circuits in the Tutte Computation Tree}

Every GM computation tree partitions $2^{E(G)}$ into
boolean intervals\cite{GordonMcMachonGreedoid}.  The boolean
intervals correspond to the leaves of the tree.  Each leaf is
characterized by subsets of externally active elements
EA and internally active elements IA.
(not explained yet here at all).
Each interval has cardinality $2^{|\text{IA}|+|\text{EA}|}$.
The broken-circuit-free subsets are those in the intervals for which
$\text{EA}=\emptyset$.  Thus the subsets with broken circuits are partitioned
among the intervals with $\text{EA}\neq\emptyset$.

Consider an interval with $\text{EA}\neq\emptyset$. It has the
form $[A, A\cup\text{IA}\cup\text{EA}]$.  Let's further partition
it into the $2^{|\text{IA}|}$ subintervals $[A\cup I, A\cup I\cup \text{EA}]$,
$I\subseteq\text{IA}$.
%We now observe, similarly to what Whitney observed, that
We now observe, like Whitney observed, that
$v=V(G/S)$ is the same for all $S\in[A\cup I, A\cup I\cup \text{EA}]$.  The
contribution of these $S$ to $\chi(G,n)$ is $n^v\sum_S(-1)^{|S|}$ $=$
$n^v(-1)^{|A\cup I|}(1-1)^{|EA|}$.

The bases also correspond to the leaves of the GM computation tree.
The interval $[A,A\cup \text{IA}\cup\text{EA}]$ corresponds to basis
$A\cup\text{IA}$.  $A$ is the set of elements contracted on the path from the
root to the leaf.  Of course the cobasis is $\overline{A}\cup\text{EA}$ where
$\overline{A}$ is the set of elements deleted on the path from the root to the
leaf.

\section{The Broken Circuit Complex}

\cite{BrokenCctComplexBryl}

The ``broken-circuit complex'' is the simplicial complex of sets that do not contain
any broken circuits.  The $f$-vector codes the number of faces of each dimension, ie.,
cardinality $-1$.
The coefficients of the chromatic polynomial (characteristic poly in general)
are the $f$-vector of the broken-circuit complex.

\section{Activities}

(Goal: Get at the facts about activities being h-vectors of broken-circuit complexes or
something.)

\[
\sum_{i=0}^d f_i(x-1)^{d-i}
=
\sum_{i=0}^d h_i(x)^{d-i}
\]

??What expansion of $\chi$ in $n$ = expansion of $\chi$ in $n-1$?

Tutte's expansion:
\[
T(G,x,y) = \sum_{\text{Bases} A\subseteq E(G)}x^{|IA(A)|}y^{|EA(A)|}
\]

Set expansion:
\[
T(G,x,y) = \sum_{A\subseteq E(G)}(x-1)^{k(A)-k(E)}(y-1)^{k(A) + |A| - |V|}
\]

\[
\chi(G,n) = (-1)^{|V|-k(G)}n^{k(G)}T(G,1-n,0)
\]

\[
\chi(G,n) = \sum_{A \text{ contains no broken circuits}}
            (-1)^{|A|}n^{|V|-|A|}
\]

\[
\chi(G,n) = (-1)^{|V|-k(G)}n^{k(G)}\sum_{A\subseteq E(G)}(-n)^{k(A)-k(E)}(-1)^{k(A) + |A| - |V|}
\]

\[
\chi(G,n) = (-1)^{|V|}(-1)^{k(G)}n^{k(G)}\sum_{A\subseteq E(G)}(-n)^{k(A)}(-n)^{-k(E)}(-1)^{k(A)}(-1)^{|A|}(-1)^{|V|}
\]

We get from ... Whitney's starting point for inclusion/exclusion:
\[
\chi(G,n) = \sum_{A\subseteq E(G)}n^{k(A)}(-1)^{|A|}
\]

(Bigger Goal: Extend that to GM activities, based on a computation tree.  Try to find
the more generalized broken circuit complex, if possible!)

\section{Applications}

Why are general computation tree orders better?  Suppose an electrical network has resistors
A, B, and C.  Properties of $N/A$ may depend more on $B$ than $C$, while properties of
$N\setminus A$ may depend more on $C$ than $B$. EG: $N=(A \text{ ser } B) \text{ par } C$.
$N/A = B \text{ par } C$, but $N\setminus A = C$.  If $g(B) >> g(C)$,
$g(N/A) = g(B) + g(C) \approx g(B)$
but $g(N\setminus A) = g(C)$

\[
R(N) = \frac{g(A)+g(B)}{g(A)g(B)+g(A)g(C)+g(B)g(C)}
\]

\[
R(N/A) = \lim_{g(A)\rightarrow\infty}R(N) = \frac{1}{g(B)+g(C)}
\]

\[
R(N\setminus A) = \lim_{g(A)\rightarrow 0}R(N) = \frac{g(B)}{g(B)g(C)} = \frac{1}{g(C)}
\]

\section{Topology, $f$\&$h$ vectors and all that}

This is addressed by Ellis-Monaghan and Merino
\cite{JEM-MerinoGraphPolyAppI}.

FROM
``Monomial Bases for Broken Circuit Complexes''
by Jason Brown and  Bruce Sagan
\cite{MonBasesBrkCircCompBrownSagan}
\begin{quote}
Let E be a finite set and let $\Delta$
be an abstract simplicial complex on E, ...

Let $f_i = f_i(\Delta)$ be the number of $S \in \Delta$ with
$|S| = i$. Then $\Delta$ has f-vector
$f = f(\Delta) = (f_0, f_1, . . . , f_r)$
as well as f-polynomial
$f(x) = f_{\Delta}(x) = f_0 + f_1x + · · · + f_rx^r$
where $x$ is a variable.

...

Another important invariant of $\Delta$ is its $h$-vector. Define a polynomial
\[
h(x) := (1 - x)^r f(\frac{x}{1-x})
\]
\[
= f_0(1 - x)^r + f_1x(1 - x)^{r-1} + f_2x^2(1-x)^{r-2} + ... + f_rx^r.
\]

Let $h_i$ be the coefficient of $x_i$ in h(x) so that

...
\end{quote}

Jason Brown and  Bruce Sagan go on to give an combinatorial interpretation
of $h_i$ when $f(-\lambda)=\pm$chromatic polynomial's Whitney's expansion.
It uses that Cohen-Macauly stuff.

Bruce and R. Bloka did a line of research following Las Vergnas'
\cite{ActOrdersMatrBasesLasVergnas} on
topology of complexes defined in terms of linearly-defined activities
\cite{ActTopPropBlokaSagan}.  In his paper,
Las Vergnas did 3 different complexes?
and a lattice ordering of matroid bases,
and wondered why M\"{o}bius function values in the lattice were zero.

\section{Literature}

New! Doman and Trinks \cite{DohmenTrinksAbsWitBrok}, paper citing
Doman's proof \cite{DohIndProofMatroids}.

Maybe an application clue from Urschel (who's also into football) et. al.
because the abstract mentions a ``heavy edge coarsening scheme''
\cite{UrschelFiedlerGraphLaplac}.

\end{enumerate}
\bibliographystyle{plain}
\bibliography{../../bib/MathOfElec}
\end{document}


\section{What is optimisation?}

\begin{frame}{What is optimisation?}

	Discipline of applied mathematics. The idea is to search values for \alert{variables}\hspace{-1pt} in a given \alert{domain} that\hspace{-1pt} maximise/minimise\hspace{-1pt} \alert{function values}.

	Can be achieved by
	\begin{itemize}[<+->]
	\item Analysing properties of functions \hspace{-1pt}/ extreme points or
	\item Applying numerical methods
	\end{itemize}
	\onslide<+->

	Optimisation has important applications in fields such as
	%
	\begin{itemize}
	\item {\bf operations research (OR)};
	\item economics;
	\item statistics;
	\item machine learning and artificial intelligence.
	\end{itemize}

\end{frame}

\subsection{Mathematical programming and optimisation}

\begin{frame}{What is optimisation?}

	In this course, optimisation is viewed as the core element of \alert{mathematical programming}.

	Math. programming is a central OR modelling paradigm:
	\begin{itemize}[<+->]
	\item {\bf variables} $\rightarrow$ decisions: business decisions, parameter definitions, settings, geometries, ...;
	\item {\bf domain} $\rightarrow$ constraints: logic, design, engineering, ...;
	\item {\bf function} $\rightarrow$ objective function: measurement of (decision) quality.
	\end{itemize}

	\onslide<+->
	However, math. programming has many applications in fields other than OR, \alert{which causes some confusion};

	We will study math. programming in its most general form: both constraints and objectives are \alert{nonlinear} functions.

\end{frame}

\begin{frame}
	\centering
	\includegraphics[scale=0.09]{Figures/Books.jpg}

\end{frame}

\subsection{Types of mathematical optimisation models}

	\begin{frame}{Types of programming}

	The \alert{simpler are the assumptions} which define a type of problems, the better are the \alert{methods to solve such problems}.

	\pause

	Some useful notation:

	\begin{itemize}[<+->]
		\item $x \in \reals^n$ - vector of (decision) variables $x_j$, $j = 1,\dots, n$;
		\item $f:\reals^n \rightarrow \reals \cup \braces{\pm \infty}$ - objective function;
		\item $X \subseteq \reals^n$ - ground set (physical constraints);
		\item $g_i, h_i : \reals^n \rightarrow \reals$ - constraint functions;
		\item $g_i(x) \leq 0$ for $i = 1, \dots, m$ - inequality constraints;
		\item $h_i(x) = 0$ for $i = 1, \dots, l$ - equality constraints.
	\end{itemize}

\end{frame}

\begin{frame}{Types of programming}

	Our goal will be to solve variations of the general problem $P$:
	%
	\begin{align*}
		(P) :~ \mini \ & f(x) \\
		\st & g_i(x) \leq 0, i = 1, \dots, m\\
		& h_i(x) = 0, i = 1, \dots, l \\
		& x \in X.
	\end{align*}
	%
	\pause
	\vspace{-24pt}
	\begin{itemize}
	\item {\bf Linear programming (LP):} \alert{linear} $f(x) = c^\top x$ with $c \in \reals^n$; constraint functions $g_i(x)$ and $h_i(x)$ are \alert{affine} ($a_i^\top x - b_i$, with $a_i \in \reals^n$, $b \in \reals$); $X = \braces{ x \in \reals^n : x_j \geq 0, j =1,\dots,n}$.
	\pause
	\item {\bf Nonlinear programming (NLP):} some (or all) of the functions $f, g_i$ or $h_i$ are \alert{nonlinear};
	\pause
	\item {\bf (Mixed-)integer programming ((M)IP):} LP where (some of the) variables are \alert{binary (or integer)}. $X \subseteq \reals^k \times \braces{0,1}^{n-k}$
	\pause
	\item {\bf Mixed-integer\hspace{-1pt} nonlinear\hspace{-2pt} programming\hspace{-2pt} (MINLP):}\hspace{-1pt} {\small MIP\hspace{-3pt} +\hspace{-3pt} NLP.}
	\end{itemize}

\end{frame}

\section{Applications}

\subsection{Resource allocation}

\begin{frame}{Resource allocation and portfolio optimisation}

	{\bf Problem statement.} Plan production that maximises return. Let
	\begin{columns}
		%% Juho
		\column{0.64\textwidth}
		\begin{itemize}
			\item {\small $I = \braces{1, \dots, i, \dots, M}$} resources;
			\item {\small $J = \braces{1, \dots, j, \dots, N}$} products;
			\item $c_j$ - return per unit of product $j\in J$;
			\item $a_{ij}$ - resource $i\in I$ requirement for making product $j\in\hspace{-1pt} J$ ;
			\item $b_i$ - availability of resource $i\in I$;
			\item $x_j$ - production of $j \in J$.
		\end{itemize}

		\column{0.4\textwidth}
		\pause
		\begin{align*}
			\maxi \ & \sum_{j \in J} c_jx_j \\
			\st & \sum_{j \in J}a_{ij}x_j \leq b_i, \forall i \in I\\
			& x_j \geq 0, \forall j \in J
		\end{align*}
	\end{columns}
	\pause
	\vfill
	{\bf Remark:}
	\vspace{-6pt}
	\begin{itemize}[<+->]
		\item notice that $\maxi f(x) = \mini - f(x)$;
		\item the base of \alert{most practical optimisation problems}; exploits mature LP technology.
	\end{itemize}

\end{frame}

\begin{frame}{Portfolio optimization}

	{\bf Problem statement.} Plan portfolio of assets to minimise exposition to risk. Let
	\begin{columns}
		\column{0.5\textwidth}
		\begin{itemize}
			\item {\small $J = \braces{1, \dots, j, \dots, N}$} assets;
			\item $\mu_j$ - expected relative return of asset $j \in J$;
			\item $\Sigma$ - covariance matrix;
			\item $\epsilon$ - minimum expected return;
			\item $x_j$ - position of asset $j \in J$
		\end{itemize}

		\column{0.4\textwidth}
		\pause
		\begin{align*}
			\mini \ &  x^\top\Sigma x  \\
			\st & \mu^\top x  \geq \epsilon\\
			& 0 \leq x_j \leq 1, \forall j \in J
		\end{align*}
	\end{columns}
	\vfill
	\pause
	{\bf Remarks:}
	\vspace{-6pt}
	\begin{itemize}
		\item The term $x^\top\Sigma x$ measures \alert{exposition to risk}. It is credited to Harry Markowitz (1952).
		\item Another important class: \alert{quadratic programming} (nonlinear).
	\end{itemize}

\end{frame}

\subsection{The pooling problem: refinery operations planning}

\begin{frame}{Refinery Operations Planning Problem}

	\begin{columns}
		\column{0.6\textwidth}
		{\bf Oil refinery operational planning}
		\begin{itemize}
			\item Goal is to maximize profit;
			\item Several possible configurations;
			\item \alert{Product property specifications} must be met;
		   \end{itemize}

		\column{0.4\textwidth}
		\begin{figure}
			\includegraphics[width=\linewidth]{figures/Refinery.png}
		\end{figure}
	\end{columns}
	\pause
	\begin{columns}
		\column{0.6\textwidth}
		{\bf Model characteristics:}
			\begin{itemize}
				\item \alert{Bilinear (nonconvex) and mixed-integer};
				\item Large number of flows;
				\item Several nonlinear constraints.
		    \end{itemize}
		\column{0.4\textwidth}
		\begin{figure}
			\includegraphics[width=\linewidth]{figures/RefinerySchema.png}
		\end{figure}
	\end{columns}

\end{frame}

\begin{frame}{Refinery Operations Planning Problem}

	\begin{columns}
		\column{0.65\textwidth}

		{\bf Objective:} maximize profit

		{\bf Variables:}
			\begin{itemize}
				\item Stream Flows {\footnotesize(crude, intermediate and final products)};
			    \item Storage;
			    \item Stream properties.
		    \end{itemize}
		\onslide<2->{

		{\bf Constraints}
			\begin{itemize}
				\item Mass balance;
			    \item Market features (supply and demand);
			    \item Unit capacities;
			    \item Stream property limits;
			    \item \alert{Calculation of mix properties (nonlinear)}.
		    \end{itemize}}
		\column{0.4\textwidth}
		% Second column
		\begin{figure}
			\includegraphics[width=\linewidth]{figures/Refinery.png}
		\end{figure}
		\begin{figure}
			\includegraphics[width=\linewidth]{figures/RefinerySchema.png}
		\end{figure}
	\end{columns}
\end{frame}

\begin{frame}{Refinery Operations Planning Problem}

	The challenging aspect is how to model the calculation of product properties in a \alert{mix}. Let:

	\begin{itemize}
		\item $x_p$ be the volume of product $p \in P$ and
		\item $q_p$ the value of a given chemical property (sulphur content, octane content, viscosity...).
	\end{itemize}
	%
	In a given mix, mass and property balances are calculated as:

	\begin{columns}
		\column{0.5\textwidth}
		\centering
		\includegraphics[scale=0.6]{Figures/Mixer.pdf}
	%
		\column{0.5\textwidth}
		%
		\begin{align*}
		& x_A = x_B + x_C \\
		& q_A = \frac{q_Bx_B + q_Cx_C}{x_A}
		\end{align*}
	%
	\end{columns}
	\pause
	{\bf Remarks:}
	\vspace{-6pt}
	\begin{itemize}
		\item More complex mixes (such as nonlinear balances) might need to be considered.
		\item These are \alert{bilinear programming} problems (nonlinear).
	\end{itemize}
\end{frame}

\subsection{Robust optimisation}

\begin{frame}{Robust optimisation}

	Is a subarea of mathematical programming concerned with \alert{uncertainty in the input data}.

	It's a risk-averse perspective that seeks \alert{protection against variability}.

	\pause

	Consider the resource allocation problem under uncertainty:
	%
	\begin{align*}
		\maxi \ &  c^\top x \\
		\st & \tilde{a}_{i}^\top x \leq b_i, \forall i \in I\\
		& x_j \geq 0, \forall j \in J,
	\end{align*}

	where $\tilde{a}_{i}$ is a \alert{random variable}.

\end{frame}

\begin{frame}{Robust optimisation}

	\includegraphics[width = 1\textwidth]{Figures/data_no_ellipsoid.pdf}

\end{frame}

\begin{frame}{Robust optimisation}

	Assume that,\hspace{-2pt} for\hspace{-2pt} any\hspace{-2pt} $i \in I$, $\tilde{a}_{i} \in \epsilon_i = \braces{\overline{a}_i + P_iu : ||u||_2 \leq \Gamma_i}$, where
	\vspace{-6pt}

	\begin{itemize}
		\item $\overline{a}_{i}$ is the nominal (average) value;
		%% Juho: I added the \epsilon here
		\item $P_i$ is the characteristic matrix of the ellipsoid $\epsilon$;
		\item $\Gamma_i$ is risk-aversion control parameter.
	\end{itemize}
	%
	\pause
	Then, the \alert{robust counterpart} can be stated as
	%
	\begin{align*}
		\maxi \ &  c^\top x \\
		\st & \maxi_{a_{i} \in \epsilon_i}\braces{a_i^\top x} \leq b_i, \forall i \in I\\
		& x_j \geq 0, \forall j \in J.
	\end{align*}
	\vspace{-6pt}
	%
	\pause
	Notice that
	$$
	\maxi_{a_{i} \in \epsilon_i}\braces{a_i^\top x} = \overline{a}_i^\top x + \maxi_u\braces{u^\top P_i x : ||u||_2 \leq \Gamma_i} = \overline{a}_i^\top x + \Gamma_i||P_i x||_2
	$$

\end{frame}

\begin{frame}{Robust optimisation}
	%
	The \alert{robust counterpart} can be equivalently stated as:
	\begin{align*}
		\maxi \ &  c^\top x \\
		\st & \overline{a}_i^\top x + \Gamma_i||P_i x||_2 \leq b_i, \forall i \in I\\
		& x_j \geq 0, \forall j \in J.
	\end{align*}
	%
	{\bf Remarks:}
	\begin{itemize}[<+->]
		\item In case data is available, $P_i$ can be obtained from the \alert{empirical covariance matrix};
		\item Values of $\Gamma_i$ can be drawn, for example, from a Chi-squared distribution. $\Gamma_i$ is sometimes called the \alert{budget of uncertainty}.
	\end{itemize}

\end{frame}

\begin{frame}{Robust optimisation}

	\includegraphics[width = 1\textwidth]{Figures/data_with_ellipsoid.pdf}

\end{frame}

\subsection{Classification: support vector machines}

\begin{frame}{Classification}

	Suppose we are given some data $D \subset \reals^n$ that can be \alert{separated} into two sets in $\reals^n$: $I^- = \braces{x_1,\dots, x_N}$ and $I^+ = \braces{x_1,\dots,x_M}$.

	Each element in $D$ is an \alert{observation} of a given set of \alert{features}; belonging to either $I^-$ or $I^+$ defines a \alert{classification}.

	\pause
	Our task is to select a function $f:\reals^n \rightarrow \reals$ from a given family of functions such that
	$$
	f(x_i) < 0, \ \forall x_i \in I^- \text{ and } f(x_i) > 0, \ \forall x_i \in I^+.
	$$
	Typically, $f$ is selected as a \alert{linear classifier}, i.e., $f(x_i) = a^\top x_i - b$.

	Of course, there is always the possibility of \alert{misclassification} and, therefore, we want to determine the \alert{best} possible classifier.

\end{frame}

\begin{frame}{Classification}

	\centering
	\includegraphics[width = \textwidth]{Figures/classes_with_classifier.pdf}

\end{frame}

\begin{frame}{Classification}

	Let us define the following \alert{error measures}:
	{\small
	\begin{align*}
		& e^-(x_i \in I^-; a, b) := \begin{cases} 0, \text{ if } a^\top x_i - b \leq 0, \\
	                                a^\top x_i - b, \text{ if } a^\top x_i - b > 0.
	                   \end{cases} \\
		& e^+(x_i \in I^+; a, b) := \begin{cases} 0, \text{ if } a^\top x_i - b \geq 0, \\
	                                b -  a^\top x_i, \text{ if } a^\top x_i - b < 0.
	                   \end{cases}
	\end{align*}}%
	\pause
	Using \alert{slack variables} $u_i$, $i = 1,\dots,M$, and $v_i$, $i = 1,\dots,N$, to represent $e^-$ and $e^+$, the optimal classifier is obtained from:
	{\small
	\begin{align*}
		(LC) :~ \mini \ & \sum_{i=1}^M u_i + \sum_{i=1}^N v_i \\
		\st & a^\top x_i - b - u_i \leq 0, i = 1,\dots,M \\
		& a^\top x_i - b + v_i \geq 0, i = 1,\dots,N \\
		& ||a||_2 = 1\\
		&u_i \geq 0, i = 1,\dots,M; v_i \geq 0, i = 1,\dots,N; a \in \reals^n, b \in \reals.
	\end{align*}}
	%
%	{\bf Remark:} notice that $||a||_2 = 1$ avoids $(a,b) = (0,0)$.
\end{frame}

\begin{frame}{Classification}

	In practice, we can enforce a \alert{slab} $S = \braces{-1 \leq a^\top x_i- b \leq 1}$ as a buffer to trade off the \alert{robustness} of the classifier to outliers.

	Accordingly, we redefine our error measures as follows.
	%
	\begin{align*}
	& e^-(x_i \in I^-; a, b) :=
	    \begin{cases} 0, \text{ if } a^\top x_i - b \leq -1, \\
	        a^\top x_i - b, \text{ if } a^\top x_i - b > -1.
	    \end{cases} \\
	& e^+(x_i \in I^+; a, b) :=
	    \begin{cases} 0, \text{ if } a^\top x_i - b \geq 1, \\
	        b -  a^\top x_i, \text{ if } a^\top x_i - b < 1.
	    \end{cases}
	\end{align*}
	%
	\pause
	$e^-$ and $e^+$ include \alert{misclassifications} and \alert{correct classifications that lie within $S$}. The latter are know as \alert{support vectors}.

	The \alert{width of $S$ is given by $2/||a||_2$}, which is the distance between the hyperplanes $a^\top x_i - b = -1$ and $a^\top x_i - b = 1$.

\end{frame}

\begin{frame}{Classification}

	The robust version of $LC$ incorporating this buffer becomes
	%
	\begin{align*}
		\mini \ & \sum_{i=1}^M u_i + \sum_{i=1}^N v_i + \gamma||a||_2^2\\
		\st & a^\top x_i - b - u_i \leq -1, \ i = 1,\dots,M \\
		& a^\top x_i - b + v_i \geq -1, \ i = 1,\dots,N \\
		& u_i \geq 0, i = 1,\dots,M; v_i \geq 0, i = 1,\dots, N; \\
		& a \in \reals^n, b \in \reals.
	\end{align*}
	\pause
	{\bf Remarks:}
	\vspace{-6pt}
	\begin{itemize}[<+->]
		\item The parameter $\gamma$ controls the \alert{trade-off} between the width of the slab $S$ and the number of observations within the slab.
		\item This quadratic programming problem is known in the machine learning literature as \alert{support vector machine} (SVM).
	\end{itemize}

\end{frame}

\begin{frame}{Classification}

	\centering
	\includegraphics[width = \textwidth]{Figures/classes_with_robust_classifier.pdf}

\end{frame}


\chapter{Some continuity and monotonicity properties of the GNK value}\label{appendix:continuity_of_GNK}

From inspection of equations \ref{knvalue1} and \ref{da_value_eq} it defined that the GNK value is a summation over maximum of minimum terms and it should be rather evident that there is present some nice continuity properties:

\begin{theorem}[GNK continuous with utilities]
For utility functions $u_i(x,y)$ if we consider any bounded perturbations $\epsilon \Delta_i(x,y)$ then the GNK value is continuous with $\epsilon$.
\end{theorem}
\begin{proof}
To demonstrate that the GNK value is continuous with change in utility functions we consider that for all $(x,y)\in A$ we consider any set of utility perturbing functions $\Delta_i(x,y)$ with a magnitude $\max_{(x,y)\in A, i\in N}|\Delta_i(x,y)| = d$.
For any coalition $S$, if we consider that advantage $v(S)$ with the original utility functions as $v_u(S)$ and with the perturbed utility function multiplied by a parameter $\epsilon$ as $v_{u+\epsilon \Delta}(S)$ then we can realise that:
$$-n\epsilon d \le v_u(S)-v_{u+\epsilon \Delta}(S) \le n\epsilon d$$
Therefore for any individual $i\in N$ the average over the advantage terms $v(S)$ for coalitions which include $i$ of size $k$ is similarly bounded.
$$-n\epsilon d \le \frac{1}{\binom{n-1}{k-1}} \sum_{\substack{S:i\in S \\ |S|=k}}v_u(S)-\frac{1}{\binom{n-1}{k-1}} \sum_{\substack{S:i\in S \\ |S|=k}}v_{u+\epsilon \Delta}(S) \le n\epsilon d$$
Therefore the average of these terms over sizes $k=1\dots n$ is also bounded.
$$-n\epsilon d \le \frac{1}{n}\sum_{k=1}^n \frac{1}{\binom{n-1}{k-1}} \sum_{\substack{S:i\in S \\ |S|=k}}v_u(S)-\frac{1}{n}\sum_{k=1}^n \frac{1}{\binom{n-1}{k-1}} \sum_{\substack{S:i\in S \\ |S|=k}}v_{u+\epsilon \Delta}(S) \le n\epsilon d$$
Which is the difference in the GNK value for an individual $i$ between the perturbed and unperturbed utility function.
Thus for any prospective utility perturbation $\Delta$ with a magnitude $d$ there is a $\delta$ ($=n\epsilon d$) such that there exists a perturbation factor $\epsilon$, such that if the utility functions are $\epsilon$ perturbed then the GNK value is $\delta$ bounded.
\end{proof}

This continuity property for utilities is potentially nice in that participants in a system under GNK, can be be assured that regardless of their bids, that small difference in their utility bids will not yield large differences in their utility payoff, this adds regularity and predictability to the system.
Conversely for a potential operator of such a hypothetical GNK system, that this continuity property may add to the predictability of the system.

The GNK also has elementary monotonicity properties that are partially inherited from its relation to the Shapley Value.

\begin{theorem}[GNK is monotonic]\label{thm:monotonicity}
If we consider advantage functions $v$ and $v'$ and the GNK value with those advantage function $\varphi^v_i$ and $\varphi^{v'}_i$.
Then for any individual $i\in N$, if all coalitions $S$ such that $i\in S$ it is true that $v'(S)\ge v(S)$ then $\varphi^{v'}_i \ge \varphi^v_i$.
\end{theorem}
\begin{proof}
$$\varphi^v_i = \frac{1}{n}\sum_{k=1}^n \frac{1}{\binom{n-1}{k-1}} \sum_{\substack{S:i\in S \\ |S|=k}}v(S) \le \frac{1}{n}\sum_{k=1}^n \frac{1}{\binom{n-1}{k-1}} \sum_{\substack{S:i\in S \\ |S|=k}}v'(S) =\varphi^{v'}_i$$
\end{proof}

This monotonicity property ensures that individuals which have uniformly higher payoff advantages are afforded more utility under the GNK, which is a basic regularity reminiscent of the logic of the GNK value itself.
Particularly, as the GNK value is an articulation of a bargaining solution concept, then individuals who have greater leverage in negotiation will (or should) have an outcome more favourable to them.
Conversely, we could imagine the potential absurdity of a system opposite were true, in that individuals with greater leverage in bargaining would be afforded less.

In considering this monotonicity property, we can ask what changes in strategies and/or utility functions and network constraints yield this kind of monotonicity condition. The most direct case is shift invariance, which is inherited from Nash bargaining roots \cite{nash2} and directly stated as an axiom in the case of the `coco' value \cite{kalai1}.

\begin{theorem}[GNK is shift invariant]\label{thm:appendix_shift_invariant}
For any two utility profiles $u^1_i(x,y)$ and $u^2_i(x,y)$, and GNK defined by these utility profiles $\varphi_i^1$ and $\varphi_i^2$.
Then for any individual $i\in N$, if $u_i^2(x,y) = u_i^1(x,y)+c$ for some constant $c$, and for all $j\neq i$ that $u^2_i(x,y) = u^1_i(x,y)$, then $\varphi_i^2 = \varphi_i^1+c$
\end{theorem}
\begin{proof}
If we consider advantage functions $v_1$ and $v_2$ defined by utility functions $u^1_i(x,y)$ and $u^2_i(x,y)$ then for any coalition $S$ including individual $i$:
\begin{align}
v_2(S) = &
\frac{1}{2}\min_{\substack{y\in A^{N\setminus S} \\ \text{s.t.}(x,y)\in A}} \left[
\max_{\substack{x\in A^S \\ \text{s.t.}\exists y,(x,y)\in A}}
	\left(\sum_{i\in S} u^1_i(x,y)+c - \sum_{i\in N\setminus S}u_i^2(x,y)\right)\right]\nonumber\\
& +
\frac{1}{2}\max_{\substack{x\in A^S \\ \text{s.t.}(x,y)\in A}} \left[
\min_{\substack{y\in A^{N\setminus S} \\ \text{s.t.}\exists x,(x,y)\in A}}
	\left(\sum_{i\in S} u^1_i(x,y)+c - \sum_{i\in N\setminus S} u_i^2(x,y) \right) \right]\nonumber\\
&= v_1(S)+c\nonumber
\end{align}
The above step simply brings the additive constant out the front of the max and min terms.
Therefore for every coalition $S$ which includes individual $i$ of size $k$, $v_2(S)=v_1(S)+c$, therefore the average of these values over such coalitions has a similar relation.
$$\frac{1}{\binom{n-1}{k-1}} \sum_{\substack{S:i\in S \\ |S|=k}}v_2(S) = \frac{1}{\binom{n-1}{k-1}} \sum_{\substack{S:i\in S \\ |S|=k}}v_1(S) + c$$
therefore the average of these averages over sizes of coalitions $k=1\dots n$ is again similar:
$$\frac{1}{n}\sum_{k=1}^n \frac{1}{\binom{n-1}{k-1}} \sum_{\substack{S:i\in S \\ |S|=k}}v_2(S) = \frac{1}{n}\sum_{k=1}^n \frac{1}{\binom{n-1}{k-1}} \sum_{\substack{S:i\in S \\ |S|=k}}v_2(S) + c$$
which is to say that $\varphi_i^2 = \varphi_i^2+c$.
\end{proof}

Shift invariance is important but not particularly interesting property. It more-or-less identifies that a participant who affords a higher utility should be rewarded with a GNK value which is that same degree higher.
This Shift invariance relation is essentially consistent with the idea that utility functions are invariant to affine transformation, more particularly translation.
If a participant modifies his/her utility function by an offset, this GNK value will afford that individual with exactly the same physical outcomes and utility transfers to give them a net utility that is that same extent offset.
This shift invariance property is good sanity check on a minimally sufficient bargaining solution concept.

So instead we also consider a very similar monotonicity property with regards to any utility perturbation that non-decreases a player's utility.

\begin{theorem}[GNK is monotonic with increasing player utility]\label{thm:appendix_monotone2}
For any two utility profiles $u^1_i(x,y)$ and $u^2_i(x,y)$, and GNK values defined by these utility profiles: $\varphi_i^1$ and $\varphi_i^2$.
Then for any individual $i\in N$, if $u_i^2(x,y) = u_i^1(x,y)+f(x,y)$ for some non-negative function $f$, and for all $j\neq i$ that $u^2_j(x,y) = u^1_j(x,y)$, then $\varphi_i^2 \ge \varphi_i^1$
\end{theorem}
\begin{proof}
If we consider advantage functions $v_1$ and $v_2$ defined by utility functions $u^1_i(x,y)$ and $u^2_i(x,y)$ then for any coalition $S$ including individual $i$:
\begin{align}
v_2(S) = &
\frac{1}{2}\min_{\substack{y\in A^{N\setminus S} \\ \text{s.t.}(x,y)\in A}} \left[
\max_{\substack{x\in A^S \\ \text{s.t.}\exists y,(x,y)\in A}}
	\left(\sum_{i\in S} u^1_i(x,y)+f(x,y) - \sum_{i\in N\setminus S}u_i^2(x,y)\right)\right]\nonumber\\
& +
\frac{1}{2}\max_{\substack{x\in A^S \\ \text{s.t.}(x,y)\in A}} \left[
\min_{\substack{y\in A^{N\setminus S} \\ \text{s.t.}\exists x,(x,y)\in A}}
	\left(\sum_{i\in S} u^1_i(x,y)+f(x,y) - \sum_{i\in N\setminus S} u_i^2(x,y) \right) \right]\nonumber\\
&= v_1(S)+c\nonumber
\end{align}
If we pull out the inner maximisation and minimisation for the perturbed and unperturbed problems respectively, ie:
$$ g_1(y) =
\max_{\substack{x\in A^S \\ \text{s.t.}\exists y,(x,y)\in A}}
	\left(\sum_{i\in S} u^1_i(x,y)+f(x,y) - \sum_{i\in N\setminus S}u_i^2(x,y)\right)
$$
$$g_2(y) =
\max_{\substack{x\in A^S \\ \text{s.t.}\exists y,(x,y)\in A}}
	\left(\sum_{i\in S} u^1_i(x,y) - \sum_{i\in N\setminus S}u_i^2(x,y)\right) $$
$$h_1(x) =
\min_{\substack{y\in A^{N\setminus S} \\ \text{s.t.}\exists x,(x,y)\in A}}
	\left(\sum_{i\in S} u^1_i(x,y)+f(x,y) - \sum_{i\in N\setminus S} u_i^2(x,y) \right)$$
$$h_2(x) =
\min_{\substack{y\in A^{N\setminus S} \\ \text{s.t.}\exists x,(x,y)\in A}}
	\left(\sum_{i\in S} u^1_i(x,y) - \sum_{i\in N\setminus S} u_i^2(x,y) \right)$$

Now since $f(x,y)$ is non-negative therefore $g_1(y) \ge g_2(y)$ and $h_1(x) \ge h_2(x)$ irrespective of $x$ and $y$.
therefore
$$\min_{\substack{y\in A^{N\setminus S} \\ \text{s.t.}(x,y)\in A}}g_1(y) \ge \min_{\substack{y\in A^{N\setminus S} \\ \text{s.t.}(x,y)\in A}}g_2(y)$$
$$\max_{\substack{x\in A^S \\ \text{s.t.}(x,y)\in A}}h_1(x) \ge \max_{\substack{x\in A^S \\ \text{s.t.}(x,y)\in A}}h_2(x)$$

and $$v_2(S) \ge v_1(S)$$
And the result that $\varphi_i^2 \ge \varphi_i^1$ follows by monotonicity (theorem \ref{thm:monotonicity}).
\end{proof}

This monotonicity property in Theorem \ref{thm:appendix_monotone2} most directly encodes the idea that the GNK value is monotone with player utilities, particularly if a players utility by some arbitrary non-negative function then their GNK value should also. it is more general in its application than the shift invariance established by Theorem \ref{thm:appendix_shift_invariant}.
and is most directly relevant to the logic of the GNK value, that players with a greater payoff advantage will be afforded more utility, and thus if a players utility increases in some way, so too should the GNK value.
Contrastingly we could imagine a system where the opposite is true, in that if a player has a higher utility for a specific outcome that the system would afford them less, would be less intuitive.

%\section{Some associated concentration inequalities}\label{Appendix:more_concentration}

%\begin{theorem}\label{hoeffdings_inequality22}
%Let $X$ be a real-valued random variable that is bounded $a\le X\le b$, with a mean $\mu$ of zero.  Then for $t>0$, the mean $\hat{\mu}$ of $n$ independent samples of $X$ is probability bounded by:
%\begin{equation}\p(\hat{\mu}-\mu\ge t)\le \left( \frac{b}{b-a}\left(\frac{b(a-t)}{a(b-t)}\right)^{\frac{a-t}{b-a}} -\frac{a}{b-a}\left(\frac{b(a-t)}{a(b-t)}\right)^{\frac{b-t}{b-a}}  \right)^n
%\end{equation}
%\end{theorem}
%\begin{proof}
%Similar to the proof in Theorem \ref{hoeffdings_inequality} we follow the same steps except do not apply Equation \ref{Hoeffdings_lemma}, leading to:
%$$ \p(\hat{\mu}\ge t) \le \left(\frac{b\exp(sa) - a\exp(sb)}{\exp(st)(b-a)}\right)^n $$
%And minimising with respect to $s$
%yields the required result.
%%$$ s = \frac{1}{b-a}\log\left(\frac{b(a - t)}{a(b - t)}\right) $$
%\end{proof}
%This concentration inequality is more powerful but more ugly and difficult to manipulate, it is also more commonly stated for variable $X$ with non-zero mean and bounded $0<X<1$:

%\begin{theorem}[Also called Hoeffding's inequality]\label{hoeffdings_inequality23}
%Let $X$ be a real-valued random variable that is bounded $0\le X\le 1$, with mean $\mu$. Then for $t>0$, the mean $\hat{\mu}$ of $n$ independent samples of $X$ is probability bounded by:
%\begin{equation}\p(\hat{\mu}-\mu\ge t)\le \left[\left(\frac{1-\mu}{1-t-\mu}\right)^{1-t-\mu}  \left(\frac{\mu}{t+\mu}\right)^{t+\mu}\right]^n
%\end{equation}
%\end{theorem}
%Which follows directly from the substitution $a=-\mu$ and $b=1-\mu$.

%Theorems \ref{hoeffdings_inequality22} and \ref{hoeffdings_inequality23} will not be used for further derivation, but to illustrate the point that

%\section{An Efron-Stein inequality for the sample variance}\label{appendix:efron_chebyshev}

%It is to be noted that one way to derive a concentration inequality for the variance is to use Chebyshev's inequality for the sample variance itself.
%Consider that if $\hat{\sigma}^2=\frac{1}{n-1}\sum_{i=1}^n(x_i-\mu)^2$ where $\mu = \frac{1}{n}\sum_{i=1}^nx_i$ is the sample mean, then:

%$$\p\left(|\hat{\sigma}^2-\sigma^2|\ge k\right)\le \frac{\text{Var}(\hat{\sigma}^2)}{k^2}$$
%which gives us a pretty straightforward error on the sample variance if we can bound $\text{Var}(\hat{\sigma}^2)$

%Now since, $\hat{\sigma}^2$ is a general function of the samples $x_1,\dots,x_n$ we can apply Efron-Stein inequality to bound it.
%The Efron-Stein inequality bounds the variance of a function of random variables by the sum of variances about each of those parameter variables.

%\begin{theorem}[Efron-Stein inequality]
%If $f$ is a function of $n$ random variables $x_1,x_2,\dots,x_n$, let $x'_1,x'_2,\dots,x'_n$ be independent copies of the same variables, letting $Z=f(x_1,x_2,\dots,x_n)$ and $Z'_i=f(x_1,x_2,\dots,x_{i-1},x'_i,x_{i+1},\dots,x_n)$
%then:
%$$ \text{Var}(Z) \le \frac{1}{2}\sum_{i=1}^n\E[(Z-Z'_i)^2]$$
%\end{theorem}

%Applying the Efron-Stein inequality to the function $\hat{\sigma}^2$ gives:
%$$\text{Var}(\hat{\sigma}^2)\le \frac{5-n}{n(n-1)}\sigma^2 + \frac{1}{n}\mu_4 $$
%where $\mu_4$ is the forth central moment.

%Therefore there are two primary options, we can eliminate the first term, or we can half reduce the second.
%For the first option, the $\sigma^2$ coefficient is non-positive for $n\ge 5$, therefore for $n\ge 5$ that:
%$$\text{Var}(\hat{\sigma}^2)\le \frac{1}{n}\mu_4 $$ and given that if the variables $x_1,\dots,x_n$ are bounded $a\le X\le b$ with $D=b-a$ then
%$\mu_4\le \frac{D^4}{16}$ and hence:
%\begin{equation}\label{appendix_eq_1}\p\left(|\hat{\sigma}^2-\sigma^2|\ge k\right)\le \frac{D^4}{16nk^2}\end{equation}

%For the second option, since $\mu_4=\E[(X-\mu)^4]\le D^2\E[(X-\mu)^2]=D^2\sigma^2$ hence:
%$$\text{Var}(\hat{\sigma}^2)\le \frac{5-n}{n(n-1)}\sigma^2 + \frac{1}{n}\mu_4 \le \left(\frac{5-n}{n(n-1)} + \frac{D^2}{n}\right)\sigma^2$$
%hence:
%\begin{equation}\label{appendix_eq_2}\p\left(|\hat{\sigma}^2-\sigma^2|\ge k\right)\le \left(\frac{5-n}{n(n-1)} + \frac{D^2}{n}\right)\frac{\sigma^2}{k^2}
%\end{equation}

%Therefore combining these two expressions \ref{appendix_eq_1} and \ref{appendix_eq_2} becomes:

%\begin{equation}\label{appendix_eq_3}\p\left(|\hat{\sigma}^2-\sigma^2|\ge k\right)\le \min\left(\left(\frac{5-n}{n(n-1)} + \frac{D^2}{n}\right)\frac{\sigma^2}{k^2},\frac{D^4}{16nk^2}\right)
%\end{equation}
%Which is valid for $n\ge 5$.


\section{Systems}

\begin{definition}[Useful fraction property]
    If there exists some $k\in \R$ such that $k=\frac{a}{b}=\frac{c}{d}$, then $\frac{a+c}{b+d}=k$ as well.
    Can be extended to $n$ equal fractions of this form.
\end{definition}


% jam 2004-09-10

\section{Simplicial Meshes}
\label{sec:simplicial-meshes}

An {\it abstract $d$-simplex} (or just {\it simplex})
$\Ssimplex$, is a set of $d+1$ elements of some ground space.
The elements of the simplex are its {\it vertices}, $\{ \Vvertex_0 \ldots \Vvertex_d \}$.
A typical ground space might be the non-negative integers,
which is what I will assume in the following.
A typical implementation would be an integer array
whose elements are sorted to facilitate equality/containment tests, etc.

The {\it dimension} of a $d$-simplex is $d$.
The {\it faces} of a simplex $\Ssimplex$ are the simplices which are subsets of $\Ssimplex$.
The {\it facets} of $\Ssimplex$ are $(d-1)$-simplices contained in $\Ssimplex$.
The {\it edges} of $\Ssimplex$ are the $1$-simplices contained in $\Ssimplex$.
If $\Tsimplex$ is a face of $\Ssimplex$,
then the face {\it opposite} $\Tsimplex$ in $\Ssimplex$
is the simplex contained those vertices of $\Ssimplex$
not in $\Tsimplex$.
If $\Tsimplex$ is the facet of $\Ssimplex = \{ \Vvertex_0 \ldots \Vvertex_d \}$
containing, wlog, vertices $\{ \Vvertex_0 \ldots \Vvertex_{d-1} \}$
then we speak of $\Vvertex_d$ as the {\it vertex opposite} $\Tsimplex$
and $\Tsimplex$ as the {\it facet opposite} $\Vvertex_d$.

An {\it oriented simplex} is a simplex together with a choice
of one of the two possible circular orderings of its vertices.
A typical implementation would add an orientation flag
to the sorted array simplex implementation.

An {\it abstract simplicial complex} (or just {\it simplicial complex}),
$\Kcomplex$, is a set of simplices
that obey an containment constraint:
if $\Ssimplex$ is in $\Kcomplex$, then all faces of $\Ssimplex$ are in $\Kcomplex$.
The complex {\it generated} by a set of simplices $\{ \Vvertex \}$,
$\Kcomplex \left( \{ \Vvertex \} \right)$ is the union of all $\{ \Vvertex \}$
and their faces.

The {\it dimension} of a simplicial complex is the maximum dimension
of any simplex in the complex.
The {\it facets} of a complex are its $(d-1)$-simplices.
The {\it edges} of a complex are its $1$-simplices.
The {\it $k$-skeleton} of a complex $\Kcomplex$
is the simplicial complex generated by the $k$-simplices in $\Kcomplex$.

A {\it pure simplicial complex} is an $d$-dimensional complex
in which every simplex is contained in some $d$-simplex in the complex,
that is, a complex which is generated by its $d$-simplices.
The {\it boundary} of a pure $d$-dimensional simplicial complex $\Kcomplex$,
$\Boundary \Kcomplex$,
is the complex generated by the $(d-1)$-simplices in $\Kcomplex$
which are contained in only 1 $d$-simplex in $\Kcomplex$.

An {\it orientable simplicial complex} is a pure $d$-dimensional simplicial complex
in which all the $d$-simplices can be assigned consistent orientations,
and an {\it oriented simplicial complex} is one in which the simplices
have been oriented consistently.
Two oriented $d$-simplices that share a $(d-1)$-dimensional facet
are {\it oriented consistently} if they have opposite orientations
relative to the shared facet. The orientation of a simplex relative to
one of its facets can be computed by permuting the vertices so that
the first $d$ vertices belong the the facet and the unshared vertex is last.
The sign of the permutation times the $\pm$ assigned orientation
is the relative orientation.

A {\it geometric realization of an abstract simplex,}
or {\it geometric simplex}, $\p(\Ssimplex)$,  associates points
in a {\it realization space,}
$\p ( \Vvertex_i ) \in \Vspace$, with the vertices of an abstract simplex.
The points are referred to as the {\it vertex positions.}
For the purposes of this paper,
I assume $\Vspace$ is
a finite dimensional real inner product space.

Note that this is not the usual definition,
in which a geometric simplex is the convex hull of its vertex positions
$\convex_span \{ \p(\Vvertex_0) \ldots \p(\Vvertex_d) \} = \convex_span ( \p(S) )$.
I prefer to keep the simplex distinct from its convex hull,
but I will often omit explicit mention of the convex hull
(eg., the 'volume of a simplex', the 'interior of a simplex', etc.).

With my definition,
a geometric simplex could be viewed as simply an abstract simplex
where the ground space is the realization space, $\Vspace$.
However, in the context of mesh optimization,
it is better to preserve the distinction between an abstract simplex
and its geometric realizations.

A {\it simplicial mesh} is a pure simplicial complex, $\Kcomplex$,
plus a mapping, $\p()$, from abstract vertices to points.

Note that this differs from the usual definition for
{\it geometric simplicial complex}
(or {\it geometric realization of a simplicial complex}),
which requires that the convex hulls of the geometric
simplices obey a geometric containment constraint:
If $\Ssimplex_0$ and $\Ssimplex_1$ are in $\Kcomplex$,
then $\convex_span ( \p( \Ssimplex_0 ) ) \intersection
\convex_span ( \p( \Ssimplex_1 ) )$
is either empty or
$\convex_span ( \p( \Ssimplex_2 ) )$ for some $\Ssimplex_2 \in \Kcomplex$.
I distinguish 'simplicial mesh' from 'geometric simplicial complex'
because it isn't feasible or desirable to maintain the geometric
containment constraint during optimization.

My definition differs from many other definitions of 'simplicial mesh',
which are restrictions of 'geometric simplicial complex', for example,
requiring a 'simplicial mesh' to be a geometric simplicial complex
which is an orientable manifold with boundary.