%------------------------------------------------------------
\section{Do's and Dont's}
%------------------------------------------------------------
\begin{frame}[fragile]{Universal quantification}
\begin{block}{\textbf{Goal:} identify objects such that ALL properties from a ``list'' hold}
\begin{enumerate}
\item<2-> \alt<1-3>{check all properties explicitly}{\sout{check all properties explicitly}}
%  \begin{itemize}
%  \item<3->[\KO]
  \onslide<3->{\hfill \dots{} \alert<3>{obsolete if properties change}}\onslide<10>{\,\textcolor{red}{\KO}}
%  \end{itemize}
\item<4-> use variable-sized conjunction (via `\lstinline{:}')
%  \begin{itemize}
%  \item<6->[\OK]
   \onslide<6->{\hfill \dots{} \alert<6>{adapts to changing facts}}\onslide<10>{\,\textcolor{green}{\OK}}
%  \end{itemize}
\item<7-> use negation of complement \onslide<9->{\hfill \dots{} \alert<9>{adapts to changing facts}}\onslide<10>{\,\textcolor{green}{\OK}}
\end{enumerate}
\end{block}
\begin{block}{\textbf{Example:} vegetables to buy}
\vspace*{-4mm}\footnotesize
\begin{semiverbatim}
veg(asparagus).       veg(cucumber).
pro(asparagus,cheap). pro(cucumber,cheap). \alt<1-4>{}{\alert<5>{pre(cheap).}}
pro(asparagus,fresh). pro(cucumber,fresh). \alt<1-4>{}{\alert<5>{pre(fresh).}}
pro(asparagus,tasty). pro(cucumber,tasty). \alt<1-4>{}{\alert<5>{pre(tasty).}}
\alt<1-2>{}{\alert<3>{pro(asparagus,clean).}}\alt<1-5>{}{                      \alt<6>{\alert<6>{pre(clean).}}{\alt<9->{\alert<9>{pre(clean).}}{}}}

\alt<1>{}{\alt<2-3>{\alert<2>{buy(X) :- veg(X), pro(X,cheap), pro(X,fresh), pro(X,tasty)}\alt<3>{, \alert{pro(X,clean)}}{}\alert<2>{.}}}{\alt<5-6>{\alert<5-6>{buy(X) :- veg(X), pro(X,P) : pre(P).}}{\alt<8->{\alert<8-9>{buy(X) :- veg(X), not bye(X).     bye(X) :- veg(X), pre(P), not pro(X,P).}}{}}}
\end{semiverbatim}
\vspace*{-2mm}
\end{block}
\end{frame}
%------------------------------------------------------------
\begin{frame}{Latin square}
\vspace*{-4mm}
\begin{minipage}[t]{0.42\linewidth}%
\begin{block}{\textbf{Given:} an $N{\times}N$ board}
\vspace*{2mm}
\begin{tabular}{c@{~}|@{}p{5mm}@{}|@{}p{5mm}@{}|@{}p{5mm}@{}|@{}p{5mm}@{}|@{}p{5mm}@{}|@{}p{5mm}@{}|}
\cline{2-7}
1 & & & & & &
\\\cline{2-7}
2 & & & & & &
\\\cline{2-7}
3 & & & & & &
\\\cline{2-7}
4 & & & & & &
\\\cline{2-7}
5 & & & & & &
\\\cline{2-7}
6 & & & & & &
\\\cline{2-7}
\multicolumn{1}{@{}c@{}}{} & \multicolumn{1}{@{}c@{}}{1} & \multicolumn{1}{@{}c@{}}{2} & \multicolumn{1}{@{}c@{}}{3} & \multicolumn{1}{@{}c@{}}{4} & \multicolumn{1}{@{}c@{}}{5} & \multicolumn{1}{@{}c@{}}{6}
\vspace*{1mm}
\end{tabular}

represented by facts:
\vspace*{-2mm}\footnotesize
\begin{semiverbatim}
square(1,1). \dots\ square(1,6).
square(2,1). \dots\ square(2,6).
square(3,1). \dots\ square(3,6).
square(4,1). \dots\ square(4,6).
square(5,1). \dots\ square(5,6).
square(6,1). \dots\ square(6,6).
\end{semiverbatim}
\vspace*{-2mm}
\end{block}
\end{minipage}%
\hfill\pause%
\begin{minipage}[t]{0.52\linewidth}%
\begin{block}{\textbf{Wanted:} assignment of $1,\dots,N$}
\vspace*{2mm}
\begin{tabular}{c@{~}|@{}p{5mm}@{}|@{}p{5mm}@{}|@{}p{5mm}@{}|@{}p{5mm}@{}|@{}p{5mm}@{}|@{}p{5mm}@{}|}
\cline{2-7}
1 & ~$1$ & ~$2$ & ~$3$ & ~$4$ & ~$5$ & ~$6$
\\\cline{2-7}
2 & ~$2$ & ~$3$ & ~$4$ & ~$5$ & ~$6$ & ~$1$
\\\cline{2-7}
3 & ~$3$ & ~$4$ & ~$5$ & ~$6$ & ~$1$ & ~$2$
\\\cline{2-7}
4 & ~$4$ & ~$5$ & ~$6$ & ~$1$ & ~$2$ & ~$3$
\\\cline{2-7}
5 & ~$5$ & ~$6$ & ~$1$ & ~$2$ & ~$3$ & ~$4$
\\\cline{2-7}
6 & ~$6$ & ~$1$ & ~$2$ & ~$3$ & ~$4$ & ~$5$
\\\cline{2-7}
\multicolumn{1}{@{}c@{}}{} & \multicolumn{1}{@{}c@{}}{1} & \multicolumn{1}{@{}c@{}}{2} & \multicolumn{1}{@{}c@{}}{3} & \multicolumn{1}{@{}c@{}}{4} & \multicolumn{1}{@{}c@{}}{5} & \multicolumn{1}{@{}c@{}}{6}
\vspace*{1mm}
\end{tabular}

represented by atoms:
\vspace*{-2mm}\footnotesize
\begin{semiverbatim}
num(1,1,1) num(1,2,2) \dots\ num(1,6,6)
num(2,1,2) num(2,2,3) \dots\ num(2,6,1)
num(3,1,3) num(3,2,4) \dots\ num(3,6,2)
num(4,1,4) num(4,2,5) \dots\ num(4,6,3)
num(5,1,5) num(5,2,6) \dots\ num(5,6,4)
num(6,1,6) num(6,2,1) \dots\ num(6,6.5)
\end{semiverbatim}
\vspace*{-2mm}
\end{block}
\end{minipage}%
\end{frame}
%------------------------------------------------------------
\begin{frame}[fragile]{Projecting Irrelevant Details Out}
\begin{block}{A Latin square encoding}
\vspace*{-4mm}\footnotesize
\begin{semiverbatim}
% DOMAIN
#const n=32. square(1..n,1..n).
\alt<1-3>{}{\alert<4>{squareX(X) :- square(X,Y).      squareY(Y) :- square(X,Y).}}

% GENERATE
1 \{ num(X,Y,N) : N = 1..n \} 1 :- square(X,Y).

% TEST
:- \alt<1-3>{square(X,\alert<2>{Y})}{\alert<4>{squareX(X)}}, N = 1..n, not num(X,Y',N) : square(X,Y').
:- \alt<1-3>{square(\alert<2>{X},Y)}{\alert<4>{squareY(Y)}}, N = 1..n, not num(X',Y,N) : square(X',Y).
\end{semiverbatim}
\vspace*{-2mm}
\end{block}
\vspace*{-2mm}
\begin{itemize}
\item<2-3>\structure{Note} \alert<2>{unreused ``singleton variables''}
\end{itemize}
%\begin{block}<3-5>
\vspace*{-4mm}
\begin{minipage}[t]{0.47\linewidth}%
\begin{block}<3-5>{\lstinline{gringo} \attach{Examples/latin_0.lp}{\lstinline{latin_0.lp}} \lstinline{| wc}}
\lstinline{105480} \alert<5>{\lstinline{2558984}} \lstinline{14005258}
\end{block}
\end{minipage}\hfill
\begin{minipage}[t]{0.47\linewidth}%
\begin{block}<5->{\lstinline{gringo} \attach{Examples/latin_1.lp}{\lstinline{latin_1.lp}} \lstinline{| wc}}
\lstinline{42056} \alert<5>{\lstinline{273672}} \lstinline{1690522}
\end{block}
\end{minipage}
% }}{} }
% \alt<1-4>{\onslide<3>{}~\lstinline{2558984}~\lstinline{13972426}}}}{\alert<5>{\lstinline{42056\ }~\lstinline{273672\ }~\lstinline{1688522}}}
%\end{block}
\end{frame}
%------------------------------------------------------------
\begin{frame}[fragile]{Unraveling Symmetric Inequalities}
\begin{block}{Another Latin square encoding}
\vspace*{-4mm}\footnotesize
\begin{semiverbatim}
% DOMAIN
#const n=32. square(1..n,1..n).

% GENERATE
1 \{ num(X,Y,N) : N = 1..n \} 1 :- square(X,Y).

% TEST
:- num(X,\alert<2>{Y},N), num(X,\alert<2>{Y'},N), \alt<1-3>{\alert<2>{Y != Y'}}{\alert<4>{Y <  Y'}}.
:- num(\alert<2>{X},Y,N), num(\alert<2>{X'},Y,N), \alt<1-3>{\alert<2>{X != X'}}{\alert<4>{X <  X'}}.
\end{semiverbatim}
\vspace*{-2mm}
\end{block}
\begin{itemize}
\item<2-3>\structure{Note} \alert<2>{duplicate ground rules
\\\small (swapping \lstinline{Y}/\lstinline{Y'} and \lstinline{X}/\lstinline{X'}
 gives the ``same'')}
\end{itemize}
\vspace*{-4mm}
\begin{minipage}[t]{0.47\linewidth}%
\begin{block}<3-5>{\lstinline{gringo} \attach{Examples/latin_2.lp}{\lstinline{latin_2.lp}} \lstinline{| wc}}
\lstinline{2071560} \alert<5>{\lstinline{12389384}} \lstinline{40906946}
\end{block}
\end{minipage}\hfill
\begin{minipage}[t]{0.47\linewidth}%
\begin{block}<5->{\lstinline{gringo} \attach{Examples/latin_3.lp}{\lstinline{latin_3.lp}} \lstinline{| wc}}
\lstinline{1055752} \alert<5>{\lstinline{6294536}} \lstinline{21099558}
\end{block}
\end{minipage}
% \begin{block}<3-5>{\lstinline{gringo} \alt<1-4>{\onslide<3>{\attach{Examples/latin_2.lp}{\lstinline{latin_2.lp}}}}{\attach{Examples/latin_3.lp}{\lstinline{latin_3.lp}}} \lstinline{| wc}}
% \alt<1-4>{\onslide<3>{\alert<3>{\lstinline{2071624}~\lstinline{12389640}~\lstinline{40915090}}}}{\alert<5>{\lstinline{1055816}~\lstinline{6294792\ }~\lstinline{21104106}}}
% \end{block}
\end{frame}
%------------------------------------------------------------
\begin{frame}[fragile]{Linearizing Existence Tests}
\begin{block}{Still another Latin square encoding}
\vspace*{-4mm}\footnotesize
\begin{semiverbatim}
% DOMAIN
#const n=32. square(1..n,1..n).

% GENERATE
1 \{ num(X,Y,N) : N = 1..n \} 1 :- square(X,Y).

% \alt<1-3>{TEST}{DEFINE \onslide<5->{+ TEST}}
\alt<4->{\alert<4>{gtX(X-1,Y,N) :- num(X,Y,N), 1 < X.     gtY(X,Y-1,N) :- num(X,Y,N), 1 < Y.}
\alert<4>{gtX(X-1,Y,N) :- gtX(X,Y,N), 1 < X.     gtY(X,Y-1,N) :- gtY(X,Y,N), 1 < Y.}
\onslide<5->{\alert<5>{ :- num(X,Y,N), gtX(X,Y,N).             :- num(X,Y,N), gtY(X,Y,N).}}}{:- num(X,\alert<2>{Y},N), num(X,\alert<2>{Y'},N), \alert<2>{Y < Y'}.
:- num(\alert<2>{X},Y,N), num(\alert<2>{X'},Y,N), \alert<2>{X < X'}.
}
\end{semiverbatim}
\vspace*{-2mm}
\end{block}
\begin{itemize}
\item<2-3>\structure{Note} \alert<2>{uniqueness of \lstinline{N} in a row/column checked by enumerating pairs!}
\end{itemize}
\vspace*{-4mm}
\begin{minipage}[t]{0.47\linewidth}%
\begin{block}<3-6>{\lstinline{gringo} \attach{Examples/latin_3.lp}{\lstinline{latin_3.lp}} \lstinline{| wc}}
\lstinline{1055752} \alert<6>{\lstinline{6294536}} \lstinline{21099558}
\end{block}
\end{minipage}\hfill
\begin{minipage}[t]{0.47\linewidth}%
\begin{block}<6->{\lstinline{gringo} \attach{Examples/latin_4.lp}{\lstinline{latin_4.lp}} \lstinline{| wc}}
\lstinline{228360} \alert<6>{\lstinline{1205256}} \lstinline{4780744}
\end{block}
\end{minipage}
% \begin{block}<3-6>{\lstinline{gringo} \alt<1-5>{\onslide<3>{\attach{Examples/latin_3.lp}{\lstinline{latin_3.lp}}}}{\attach{Examples/latin_4.lp}{\lstinline{latin_4.lp}}} \lstinline{| wc}}
% \alt<1-5>{\onslide<3>{\alert<3>{\lstinline{1055816}~\lstinline{6294792}~\lstinline{21104106}}}}{\alert<6>{\lstinline{228424\ }~\lstinline{1205512}~\lstinline{4782138}}}
% \end{block}
\end{frame}
%------------------------------------------------------------
\begin{frame}[fragile]{Assigning Aggregate Values}
\begin{block}{Yet another Latin square encoding}
\vspace*{-4mm}\footnotesize
\begin{semiverbatim}
\alert<2-3>{% DOMAIN}
#const n=32. square(1..n,1..n).\only<1-6>{
\alert<2>{sigma(S) :- \alert<3>{S = #sum \{ X:square(X,n) \}}.}\alt<3>{\hfill\textcolor{green}{\OK}}{}}

% GENERATE
1 \{ num(X,Y,N) : N = 1..n \} 1 :- square(X,Y).

\alt<1-8>{\alert<4-6>{% DEFINE + TEST}
\alert<4>{occX(X,N,C) :- X = 1..n, N = 1..n, \alt<5>{\alert{C \{ num(X,Y,N) \} C, C = 0..n}.}{\alert<6>{C = \{ num(X,Y,N) \}}.}\alt<6>{\hfill\KO}{}}
\alert<4>{occY(Y,N,C) :- Y = 1..n, N = 1..n, \alt<5>{\alert{C \{ num(X,Y,N) \} C, C = 0..n}.}{\alert<6>{C = \{ num(X,Y,N) \}}.}\alt<6>{\hfill\KO}{}}
\alert<4>{:- occX(X,N,C), C != 1.  :- occY(Y,N,C), C != 1.}}{\alert<9>{% TEST
:- X = 1..n, N = 1..n, not 1 \{ num(X,Y,N) \} 1.
:- Y = 1..n, N = 1..n, not 1 \{ num(X,Y,N) \} 1.
}}

% DISPLAY
#show num/3. \only<1-6>{\alert<2>{#show sigma/1.}}
\end{semiverbatim}
\vspace*{-2mm}
\end{block}
\alt<5>{%
\begin{itemize}
\item\structure{Note} \alert{internal transformation by \lstinline{gringo}}
\end{itemize}\vspace*{1mm}}{%
\vspace*{-7mm}
\begin{minipage}[t]{0.47\linewidth}%
\begin{block}<7->{\lstinline{gringo} \attach{Examples/latin_5.lp}{\lstinline{latin_5.lp}} \lstinline{| wc}}
\alt<7>{}{\lstinline{304136} \alert<10>{\lstinline{5778440}} \lstinline{30252505}}
\end{block}
\end{minipage}\hfill
\begin{minipage}[t]{0.47\linewidth}%
\begin{block}<9->{\lstinline{gringo} \attach{Examples/latin_6.lp}{\lstinline{latin_6.lp}} \lstinline{| wc}}
\alt<9>{}{\lstinline{48136} \alert<10>{\lstinline{373768}} \lstinline{2185042}}
\end{block}
\end{minipage}}
\end{frame}
%------------------------------------------------------------
\begin{frame}[fragile]{Breaking Symmetries}
\begin{block}{The ultimate Latin square encoding?}
\vspace*{-4mm}\footnotesize
\begin{semiverbatim}
% DOMAIN
#const n=32. square(1..n,1..n).

% GENERATE
1 \{ num(X,Y,N) : N = 1..n \} 1 :- square(X,Y).

% TEST
:- X = 1..n, N = 1..n, not 1 \{ num(X,Y,N) \} 1.
:- Y = 1..n, N = 1..n, not 1 \{ num(X,Y,N) \} 1.
\alt<1-3,6-7>{}{\alert<4,8>{:- square(1,Y), not num(1,Y,Y). % Symmetry Breaking}}

% DISPLAY
#show num/3.
\end{semiverbatim}
\vspace*{-2mm}
\end{block}
\alt<6->{\vspace*{-5mm}%
\begin{block}{\alert<6,8>{\lstinline{gringo -c}} \alert{\lstinline{n=5}} \alt<8-9>{\attach{Examples/latin_7.lp}{\lstinline{latin_7.lp}}}{\attach{Examples/latin_6.lp}{\lstinline{latin_6.lp}}} \alert<6,8>{\lstinline{| clasp -q 0}}}
\alt<7-8>{\onslide<7>{%
\alert{\lstinline{Models      : 161280}}\qquad
\alert{\lstinline{Time        : 2.078s}}}}{\alt<6>{
\lstinline{\ }}{%
\alert{\lstinline{Models      : 1344\ }}\qquad
\alert{\lstinline{\ Time        : 0.024s}}}}
\end{block}\vspace*{-1mm}}{\alt<1>{}{%
\begin{itemize}
\item\structure{Note} \alt<5>{Let's compare \alert{enumeration} speed!}{\alt<2>{\alert{many symmetric solutions}
\\\small (mirroring, rotation, value permutation)}{\alert<3>{easy and safe to fix a full row/column!}}}
\end{itemize}}}
\end{frame}
%------------------------------------------------------------
\section{Hints}
%------------------------------------------------------------
\begin{frame}{Encode With Care!}
  \begin{enumerate}
  \item Create a \alert<1>{working} encoding
    \begin{itemize}
    \item<2->[Q1:] Do you need to modify the encoding if the facts change?
    \item<2->[Q2:] Are all variables significant (or statically functionally dependent)?
    \item<2->[Q3:] Can there be (many) identic ground rules?
    \item<2->[Q4:] Do you enumerate pairs of values (to test uniqueness)?
    \item<2->[Q5:] Do you assign dynamic aggregate values (to check a fixed bound)?
    \item<2->[Q6:] Do you admit (obvious) symmetric solutions?
    \item<3->[Q7:] Do you have additional domain knowledge simplifying the problem?
    \item<4->[Q8:] Are you aware of anything else that, if encoded,
                   would reduce grounding and/or solving efforts?
    \end{itemize}
  \item<1-> \alert<5>{Revise until no ``Yes'' answer!}
    \begin{itemize}
    \item<6->\structure{Note} \alert<6>{If the format of facts makes encoding painful
                        (for instance,
                        abusing grounding for ``scientific calculations''),
                        revise the fact format as well.}
    \end{itemize}
  \end{enumerate}
\end{frame}
%------------------------------------------------------------
\begin{frame}{Some Hints on (Preventing) Debugging}
\begin{block}{Kinds of errors}
\vspace*{-2mm}
  \begin{itemize}
  \item \alert<2>{syntactic} \hfill\onslide<2->{\dots{} follow error messages by the grounder}
  \item \alert<3->{semantic} \hfill\onslide<3->{\dots{} (most likely) encoding/intention mismatch}
  \end{itemize}
\vspace*{-2mm}
\end{block}
\begin{block}<4->{Ways to identify semantic errors (early)}
  \begin{enumerate}
  \item<4-> \alert{develop and test incrementally}
    \begin{itemize}
    \item prepare toy instances with ``interesting features''
    \item build the encoding bottom-up and verify additions (eg.\ new predicates)
    \end{itemize}
  \item<5-> \alert{compare the encoded to the intended meaning}
    \begin{itemize}
    \item check whether the grounding fits (use \alert{\lstinline{gringo --text}})
    \item if stable models are unintended, investigate conditions that fail to hold
    \item if stable models are missing, examine integrity constraints (add heads)
    \end{itemize}
  \item<6-> ask tools (eg.\ {\footnotesize\url{http://www.kr.tuwien.ac.at/research/projects/mmdasp/}})
  \end{enumerate}
\end{block}
\end{frame}
%------------------------------------------------------------
\begin{frame}{Overcoming Performance Bottlenecks}
\begin{block}{Grounding}
\vspace*{-2mm}
\begin{itemize}
\item monitor \alert{time} spent by and output \alert{size} of \lstinline{gringo}
  \begin{enumerate}
  \item system tools   \ (eg.\ \lstinline{time(gringo [}\dots{}\lstinline{] | wc)})
  \item grounding info \ (eg.\ \lstinline{gringo --text})
  \end{enumerate}
  \item<2->\structure{Note} once identified, \alert{reformulate} ``critical'' logic program parts
\end{itemize}
\end{block}
\begin{block}<3->{Solving}
\vspace*{-2mm}
\begin{itemize}
\item check solving statistics (use \alert{\lstinline{clasp --stats}})
\item<4->\structure{Note} if great search efforts (\alert{\lstinline{Conflicts}}/\lstinline{Choices}/\lstinline{Restarts}), then
  \begin{enumerate}
  \item<5-> try prefabricated settings (using \lstinline{clasp} option `\lstinline{--configuration}')
  \item<5-> try auto-configuration (offered by \lstinline{claspfolio} or \lstinline{accclingo})
  \item<5-> try manual fine-tuning (requires expert knowledge!)
  \item<6-> if possible, reformulate the problem or add domain knowledge
            (``redundant'' constraints) to help the solver
  \end{enumerate}
\end{itemize}
\end{block}
\end{frame}
%------------------------------------------------------------

%%% Local Variables:
%%% mode: latex
%%% TeX-PDF-mode: t
%%% TeX-master: "../asp"
%%% End:


\documentclass{article}
\usepackage{amsmath,amssymb}
\usepackage{hyperref}
\usepackage{graphicx}

\title{\bf{Axisymmetric Drag Polar Analysis}}
\author{Nicholas Malaya \\ Institute for Computational Engineering and Sciences \\ University of Texas at Austin} \date{}

\begin{document}
\maketitle

\newpage

The power extracted by the turbine is,
\begin{equation}
 P = \Omega Q
\end{equation}
where the torque, Q, is,
\begin{equation}
 Q = B \int_{r_{\text{min}}}^{r_{\text{max}}} F'_{\tau}\, r\, dr.
\end{equation}
Here, B is the number of blades $r_{\text{max}}$ and $r_{\text{min}}$
are the turbine radii, and $F'_{\tau}$ is the force per unit
length on the turbine, which is,
\begin{equation}
 F'_{\tau} = \frac{1}{2}\rho U^2 \, c \, C_{\tau}.
\end{equation}
$U$ is magnitude of velocity. $c$ is the blade chord
length, which is assumed to be constant (not a function of the radius,
for instance). Finally, $C_{\tau}$ is the tangential force coefficient,
which depends on the local lift and drap coefficients, as well as the
flow angle, $\phi$,
\begin{equation}
 C_{\tau} = C_L \,\text{sin}(\phi) + C_D \,\text{cos}(\phi)
\end{equation}
Combining the equations above results in an expression for the power
that explicitly depends on the lift and drag coefficients,
\begin{equation*}
 P = \frac{\rho\, c\, \Omega B}{2}
  \int_{r_{\text{min}}}^{r_{\text{max}}} U(r)^2 \left(C_L
						     \,\text{sin}(\phi)
						     + C_D
						     \,\text{cos}(\phi)
						    \right) r\,dr.
\end{equation*}
This equation is separable,
\begin{align}
 P_L = \frac{\rho\, c\, \Omega B}{2}
  \int_{r_{\text{min}}}^{r_{\text{max}}} U(r)^2 \, C_L(\phi,r)
 \,\text{sin}(\phi)\, r\,dr,  \label{lift} \\
 P_D = \frac{\rho\, c\, \Omega B}{2}
  \int_{r_{\text{min}}}^{r_{\text{max}}} U(r)^2 \, C_D(\phi,r) \,\text{cos}(\phi)\, r\,dr. \label{drag}
\end{align}
Note that we have assumed $C_D = C_D(\phi,r)$ and $C_L = C_L(\phi,r)$,
namely, that the coefficients vary with the flow direction and may vary
radially, due to twisting the blade angle. Furthermore, the flow
direction, $\phi$, varies with radial location, in that $\phi=\phi(r)$.
Our objective is now to discover what these unknown functions of lift
and drag are. To do this, we specify an optimization problem such that,
\begin{equation*}
 \text{Max } P(C_L,C_D) \quad \text{ subject to: }
  \begin{cases}
   |C_L| < C_L^{\text{Max}}, \\
   0 < C_D < C_D^{\text{Max}}. \\
  \end{cases}
\end{equation*}

In words, the drag must be specified to be greater than zero, but
the lift can be negative. For these conditions, we are interested in
largest attainable values. For the drag coefficient, $C_D^{\text{Max}}$
is two. % refmunson
This corresponds to a flat plate perpendicular to the flow.
The lift coefficient peak is about 1.75. This design is not necessarily
physically realizable, but represents an absolute maximum that one
appears conceivable.

The integral shown in Equations \ref{lift} above is bounded by
Schwarz's Inequality,
\begin{align}
  \left[\int_{r_{\text{min}}}^{r_{\text{max}}} C_L(\phi,r)\, U(r)^2
 \,\text{sin}(\phi)\, r\,dr \right]^2 \le
 \int_{r_{\text{min}}}^{r_{\text{max}}} C_L^2(\phi,r) dr \,
 \int_{r_{\text{min}}}^{r_{\text{max}}} U(r)^4
 \,\text{sin}^2(\phi)\, r^2\,dr.
\end{align}
In this way the quantity
\begin{equation}
 \int_{r_{\text{min}}}^{r_{\text{max}}} C_L^2(\phi,r) dr \,,
\end{equation}
is clearly maximized when $C_L(\phi,r) = C_L^{\text{max}}$.
The result for Equation \ref{drag} is identical. Thus, the drag polars
have the form,
\begin{align*}
 &C_L(\phi) =
  \begin{cases}
    1.75& \quad 0^{\circ} \le \phi \le 180^{\circ}, \\
   -1.75& \quad 180^{\circ} \le \phi \le 360^{\circ}.  \\
  \end{cases}\\
 &C_D(\phi) =
  \begin{cases}
    2.0& \quad -90^{\circ} \le \phi \le 90^{\circ}, \\
      0& \quad 90^{\circ} \le \phi \le 270^{\circ}.  \\
  \end{cases}\\
\end{align*}
The plot of these drag polars are shown in Figure \ref{drags}.

\begin{figure}[!htb]
  \begin{center}
    \includegraphics[width = 12 cm]{figs/drags}
    \caption{The idealized drag polars.}
    \label{drags}
  \end{center}
\end{figure}

\newpage
\section{Questions}

\begin{itemize}
 \item Does this need regularization to ensure well-posedness?
 \item Boundary conditions are periodic
 \item What about supporting twist? (e.g. $\beta = \beta(r)$)
 \item Can we constrain $C_L, C_D$?
 \item Is this just linear programming?
\end{itemize}

\end{document}


\label{ch:three}

\section{The abstraction through random variables}
    We have mentioned many times the idea of \textit{factoring out} the enemy in the previous chapter, but we never actually expressed formally what we meant with that for CKA.
    In order to make reasoning like this it is needed to model the concepts of \textit{message} and \textit{information} in a computation-able way.
    Shannon studied this problem and published his results in \cite{Shannon49} which is now the foundation of modern information theory and cryptography.

    Let us suppose that over a certain alphabet there exist messages $M_1,M_2,\ldots M_n$ and each message has a probability $P(M_i)$ to be chosen (i.e. transmitted).
    Each message $M_i$ is encrypted into its counterpart $E_i$.
    An enemy intercepts $E_i$ and can therefore calculate the probability of message $M_i$ corresponding to the received encrypted version; namely the conditional probability $P(M_i|E_i)$.
    Shannon states that to obtain perfect secrecy of the message $P(M|E)$ must equal $P(M)$ for all $E$ and all $M$.
    From Bayes' formula
    \begin{equation}
    	P(M|E) = \frac{P(M)P(E|M)}{P(E)}
    \end{equation}
    it follows that $P(E|M)=P(E)$ is an equivalent condition for perfect secrecy.
    That is, the probability of the cipher-text $E$ must be independent of knowing the message $M$.
    This translates into the case where intercepting the encrypted message gives the enemy no information.

    Now imagine the message is transmitted by a satellite to Alice and Bob.
    Eve is also listening. This is an example of a public channel.
    We end up with three versions of the message\footnotemark : Alice's version $X$, Bob's $Y$ and Eve's version $Z$.
    To express the whole space of combinations of possible messages, we need the joint probability $P_{XYZ}$.
    Then the idea of "factoring out Eve" takes the meaning of obtaining
    \begin{equation}
    	P_{XYZ}(x,y,z) = P_{XY}(x,y)\cdot P_Z(z) \; \forall x,y,z
    \end{equation}
    so that the marginal of $P_{XYZ}$ over $Z$ --- i.e. the part of the distribution owned by Eve --- is now product with variables $X$ and $Y$. $Z$ is independent from $X$ and $Y$.

    \footnotetext{Ideally the three messages are identical, but just consider that the message is sent through a noisy channel: each receiver will have slight variations of the message, hence the distinction.}

    Information theory builds on probability theory, which provides us with useful measures and rules to operate on those probabilities.
    The most important to us are the marginal $P_X(x)$ of joint probabilities $P_{XY}(x,y)$, the entropy $\Ent (X)$, the correlation and mutual information $\I(X;Y)$ of random variables.

%    In classical information theory a message is defined as a repetition of an experiment on random variables with a (joint) probability distribution $P_{X_1X_2\ldots X_n}$.
%    The range of the random variable $X$ is the size of the alphabet with which we are communicating.
%    For example if the message is written in English the alphabet is composed of $26$ letters, or $62$ if we include numbers and distinguish upper and lower case letters.
%    The probability of a word in a message can be given, for example, by the frequency of that word in the English language.
%    Moreover, the probability of a word (or letter) to follow another can be dependent on the previous realizations of $P$.
%    Probability theory provides rules and operations to manipulate and observe these probability distributions.
%    The most important for us are the entropy $\Ent (X)$, the correlation and mutual information $\I(X;Y)$ of random variables and the marginal $P_X$ of joint probabilities $P_{XY}$.

\section{Local operations and public communication (LOPC)}
    By local operations and public communication we mean operations carried out on bit strings sampled from $P_{XYZ}(x,y,z)$ and can then be modeled as channels.
    We can mix different distributions together or trace out the marginal.
    Communication over an actual realization of a channel is noisy.
    That noise is also a form of operations on the probability distribution.
    Operations can also be carried out directly by the parties.
    This is of more interest because we have control over those operations.

    Take for example the Diffie-Hellman method illustrated in section \ref{Diffie}.
    steps $1$ and $4$ are \emph{public communication} and steps $2$,$3$ and $5$ are \emph{local operations}.
    Local operations are conducted privately, meaning that everything that happens is only accessible to the party conducting the operation.
    Other parties can not know what a local operation involved.
    Public communication is everything that is communicated in clear by parties, or that an eavesdropper can intercept.
    The totality of what an enemy knows from a protocol --- apart from the functioning of the protocol itself --- comes from public communication and the partial trace.
    Through public communication Alice and Bob can also send instructions on what to do in their local operations, like in BB84.

\section{Secret-key rate} \label{seckeyrate}
    The secret-key rate $\keyrate{X}{Y}{Z}$ is roughly a quantification of the maximal amount of correlated bits between Alice and Bob extractable from an arbitrarily large number of independent realizations of a distribution $P_{XYZ}$ that are not known to Eve.
    It was introduced by Maurer in \cite{Maur93} to prove lower bounds on the achievable size of a key shared by Alice and Bob in secrecy.
    It can be seen as a classical analog of the \textit{distillable entanglement} in \cite{BDS96}.
    Formally the secret key rate is defined as follows.
    \begin{definition}\cite{Maur93, RW03}
    Let $P_{XYZ}$ be a joint probability distribution. The secret-key rate $\keyrate{X}{Y}{Z}$ of $X$ and $Y$ with respect to $Z$ is the largest $R\in \mathbb{R}$ such that for all $\epsilon > 0$ there exists a protocol, that involves a sufficiently large number $N$ of realizations of $X^N$ of $X$ and $Y^N$ of $Y$, that satisfies:
    Alice and Bob compute, at the end of the protocol, random variables $S_A$ and $S_B$, respectively, with range $\mathcal{S}$ such that there exists a random variable $S$ with the same range and
    \begin{equation*}
    	\Ent(S) = \log |S| \geq RN\; ,
    \end{equation*}
    \begin{equation*}
    	P[S_A=S_B=S]>1-\epsilon\; ,
    \end{equation*}
    \begin{equation*}
    	\I(S;CZ^N) < \epsilon
    \end{equation*}
	Here $C$ is the totality of the protocol public communication; $\I(S;CZ^N)$ is the mutual information between the secret key and what the eavesdropper Eve knows (ref. \ref{mutInfo}).
    \end{definition}

    The secret-key rate is a useful measure of the amount of extractable secrecy --- hence, key bits --- from a protocol with LOPC.
    It would be ideal to be able to express it as a function $\keyrate{X}{Y}{Z} = S(P_{XYZ})$.
    Instead, it can be bounded by two functions\cite{Maur93}
    \begin{equation}\label{eq:skrbound1}
    	\keyrate{X}{Y}{Z} \leq \min[\I(X;Y),\, \I(X;Y|Z)]
    \end{equation}
    \begin{equation}\label{eq:skrbound2}
    	\keyrate{X}{Y}{Z} \geq \max[\I(Y;X) - \I(Z;X),\, \I(X;Y) - \I(Z,Y)]
    \end{equation}
    Those are not tight bounds. In fact in Eq. \ref{eq:skrbound2} the secret-key rate can be positive even when the right-hand side is negative.


\section{Forced Vibrations}
\noindent
Now that we have some powerful methods for solving higher order equations, we can think about forced vibrations and understand ideas like beats and resonance.\\

\noindent
The equation we're trying to solve is
\begin{equation*}
	my'' + by' + ky = F_{\text{ext}}(t)
\end{equation*}
We'll assume that $F_{\text{ext}}(t) = F_0\cos{(\gamma t)}$ so our equation becomes.
\begin{equation*}
	my'' + by' + ky = F_0\cos{\gamma}
\end{equation*}

\noindent
We'll look at the undamped and damped cases separately.

\input{./higherOrder/forcedVibrs/undampedForcedVibrs.tex}
\input{./higherOrder/forcedVibrs/dampedForcedVibrs.tex}


\lab{The PageRank Algorithm}{The PageRank Algorithm}
\label{lab:PageRank}
\objective{Many real-world systems---the internet, transportation grids, social media, and so on---can be represented as graphs (networks).
The PageRank algorithm is one way of ranking the nodes in a graph by importance.
Though it is a relatively simple algorithm, the idea gave birth to the Google search engine in 1998 and has shaped much of the information age since then.
In this lab, we implement the PageRank algorithm with a few different approaches, then use it to rank the nodes of a few different networks.
% The results may be of interest to fans of NCAA March Madness brackets.
}

\begin{comment} % Old introduction.
When you enter keywords into Google's search engine, Google finds every page containing your keywords and lists the pages in order of their \emph{rank}.
The rank of a page reflects many factors, including how often the page is visited and how connected it is to other pages.

As of 2013, the PageRank algorithm is one of over 200 algorithms that Google uses to determine the \emph{rank}, or relative importance, of a webpage.
Named for Larry Page, cofounder of Google, this algorithm ranks pages based on how many other pages link to them.

The PageRank algorithm is also used in applications other than internet search engines.
For example, it has been used to rank graduate institutions and the impact factor of journals, and it has been used in some biological applications.
\end{comment}

\section*{The PageRank Model} % ===============================================

The internet is a collection of webpages, each of which may have a hyperlink to any other page.
One possible model for a set of $n$ webpages is a directed graph, where each node represents a page and node $j$ points to node $i$ if page $j$ links to page $i$.
The corresponding \emph{adjacency matrix} $A$ satisfies $A_{ij} = 1$ if node $j$ links to node $i$ and $A_{ij} = 0$ otherwise.

\begin{comment} % OLD TIKZPICTURE.
\begin{tikzpicture}[node distance=1.75cm, thick ]

\node[draw=none](2)[]{2};
\node[draw=none](3)[right of=2]{3};
\node[draw=none](4)[right of=3]{4};
\node[draw=none](5)[right of=4]{5};
\node[draw=none](6)[right of=5]{6};
\node[draw=none](1)[above of=3]{1};
\node[draw=none, node distance=2.5cm](0)[right of=1]{0};
\node[draw=none](dummy)[above right of=0]{};
\node[draw=none, node distance=.5cm](7)[below
  of=dummy]{7};

\foreach \x/\y in {3/2, 4/5, 5/6, 1/0, 3/0, 4/0, 5/0} \draw[->,
  >=stealth'](\x)--(\y);
\draw[->, >=stealth'](6)--(0);
\draw[->, >=stealth', shorten >= .1cm](7)edge[bend left=20](0);
\draw[->, >=stealth', shorten <= .1cm](0)edge[bend left=20](7);
\draw[->, >=stealth', shorten <= .1cm](3)edge[bend right=40](6.9,-.25);
\draw[->, >=stealth', shorten <= .1cm](4)edge[bend right](6);
\end{tikzpicture}
\end{comment}

\begin{figure}[H] % directed network and adjacency matrix.
\captionsetup[subfigure]{justification=centering}
\centering
\begin{subfigure}{.45\textwidth}
\centering
\begin{tikzpicture}[normalcircle/.style={draw,circle,minimum size=.75cm,fill=none,thick,node distance=2.5cm}]
% Nodes
\node[normalcircle] (A) {a};
\node[normalcircle] (B) [above of=A] {b};
\node[normalcircle] (C) [right of=B] {c};
\node[normalcircle] (D) [below of=C] {d};
% Edges
\draw[bend right=60,thick,->,>=stealth'] (D) edge (C);
\foreach \a/\b in {A/B,A/C,A/D,C/B,C/D} \draw[thick,->,>=stealth'] (\a) edge (\b);
\end{tikzpicture}
\end{subfigure}
%
\begin{subfigure}{.45\textwidth}
\centering
\begin{align*}
A = \begin{blockarray}{ccccccc}
& & \small\text{\textcolor{gray}{a}} & \small\text{\textcolor{gray}{b}} & \small\text{\textcolor{gray}{c}} & \small\text{\textcolor{gray}{d}} & \\
\begin{block}{c[cccccc]}
\small\text{\textcolor{gray}{a}} & & 0 & 0 & 0 & 0 & \topstrut\\
\small\text{\textcolor{gray}{b}} & & 1 & 0 & 1 & 0 & \\
\small\text{\textcolor{gray}{c}} & & 1 & 0 & 0 & 1 & \\
\small\text{\textcolor{gray}{d}} & & 1 & 0 & 1 & 0 & \botstrut\\
\end{block}\end{blockarray}
\end{align*}
\end{subfigure}
\caption{A directed unweighted graph with four nodes, together with its adjacency matrix.
Note that the column for node b is all zeros, indicating that b is a \emph{sink}---a node that doesn't point to any other node.}
\label{fig:pagerank-basic}
\end{figure}

If $n$ users start on random pages in the network and click on a link every 5 minutes, which page in the network will have the most views after an hour?
Which will have the fewest?
The goal of the PageRank algorithm is to solve this problem in general, therefore determining how ``important'' each webpage is.

% A link from a more important page counts more than one from a less important page; if a node has many edges pointing to it, its outgoing edges gain importance.
% For example, in Figure \ref{fig:pagerank-basic} we would expect node 0 to have a very high rank because every other node links to it.
% Consequently, we would expect node 7 to have a fairly high rank because node 0 links to it, even though node 0 is the only node to do so.

Before diving into the mathematics, there is a potential problem with the model.
What happens if a webpage doesn't have any outgoing links, like node b in Figure \ref{fig:pagerank-basic}?
Eventually, all of the users will end up on page b and be stuck there forever.
To obtain a more realistic model, modify each sink in the graph by adding edges from the sink to every node in the graph.
This means users on a page with no links can start over by selecting a random webpage.

\begin{figure}[H]
\captionsetup[subfigure]{justification=centering}
\centering
\begin{subfigure}{.45\textwidth}
\centering
\begin{tikzpicture}[normalcircle/.style={draw,circle,minimum size=.75cm,fill=none,thick,node distance=2.5cm}]
% Nodes
\node[normalcircle] (A) {a};
\node[normalcircle] (B) [above of=A, fill=blue!10] {b};
\node[normalcircle] (C) [right of=B] {c};
\node[normalcircle] (D) [below of=C] {d};
% Edges
\draw[bend right=60,thick,->,>=stealth'] (D) edge (C);
\draw[bend left=60,thick,->,>=stealth',blue] (B) edge (C);
\draw[bend right=60,thick,->,>=stealth',blue] (B) edge (A);
\foreach \a/\b in {A/B,A/C,A/D,C/B,C/D} \draw[thick,->,>=stealth'] (\a) edge (\b);
\draw[thick,->,>=stealth',blue] (B) edge (D);
\draw[thick,->,>=stealth',shorten >=1pt,blue] (B) to [out=110,in=170,loop,looseness=4.5] (B);
\end{tikzpicture}
\end{subfigure}
%
\begin{subfigure}{.45\textwidth}
\centering
\begin{align*}
\widetilde{A} = \begin{blockarray}{ccccccc}
& & \small\text{\textcolor{gray}{a}} & \small\text{b} & \small\text{\textcolor{gray}{c}} & \small\text{\textcolor{gray}{d}} & \\
\begin{block}{c[cccccc]}
\small\text{\textcolor{gray}{a}} & & 0 & \textcolor{blue}{1} & 0 & 0 & \topstrut\\
\small\text{\textcolor{gray}{b}} & & 1 & \textcolor{blue}{1} & 1 & 0 & \\
\small\text{\textcolor{gray}{c}} & & 1 & \textcolor{blue}{1} & 0 & 1 & \\
\small\text{\textcolor{gray}{d}} & & 1 & \textcolor{blue}{1} & 1 & 0 & \botstrut\\
\end{block}\end{blockarray}
\end{align*}
\end{subfigure}
\caption{Here the graph in Figure \ref{fig:pagerank-basic} has been modified to guarantee that node b is no longer a sink (the added links are blue).
We denote the modified adjacency matrix by $\widetilde{A}$.}
\label{fig:pagerank-nosinks}
\end{figure}

Now let $p_k(t)$ be the likelihood that a particular internet user is surfing webpage $k$ at time $t$.
Suppose at time $t+1$, the user clicks on a link to page $i$.
Then $p_i(t+1)$ can be computed by counting the number of links pointing to page $i$, weighted by the total number of outgoing links for each node.

As an example, consider the graph in Figure \ref{fig:pagerank-nosinks}.
To get to page a at time $t + 1$, the user had to be on page b at time $t$.
Since there are three links from page b to other pages, assuming links are chosen with equal likelihood,
\begin{align*}
p_\text{a}(t+1) = \frac{1}{3}p_\text{b}(t).
\end{align*}
Similarly, to get to page b at time $t+1$, the user had to have been on page a or c at time $t$.
Since a has $3$ outgoing edges and c has $2$ outgoing edges,
\begin{align*}
p_\text{b}(t+1)
= \frac{1}{3}p_\text{a}(t)
+ \frac{1}{2}p_\text{c}(t).
\end{align*}
The previous equations can be written in a way that hints at a more general linear form:
\begin{align*}
p_\text{a}(t+1)
    &= 0p_\text{a}(t)
    + \frac{1}{3}p_\text{b}(t)
    + 0p_\text{c}(t)
    + 0p_\text{d}(t),
\\
p_\text{b}(t+1)
    &= \frac{1}{3}p_\text{a}(t)
    + 0p_\text{b}(t)
    + \frac{1}{2}p_\text{c}(t)
    + 0p_\text{d}(t).
\end{align*}
The coefficients of the terms on the right hand side are precisely the entries of the $i$th row of the modified adjacency matrix $\widetilde{A}$, divided by the $j$th column sum.
In general, $p_i(t+1)$ satisfies
\begin{equation}\label{eq:pagerank-single-initial}
p_i(t+1) = \sum_{j=1}^{n} \widetilde{A}_{ij} \frac{p_j(t)}{\sum_{k=1}^n \widetilde{A}_{kj}}.
\end{equation}
Note that the column sum $\sum_{k=1}^n \widetilde{A}_{kj}$ in the denominator can never be zero since, after the fix in Figure \ref{fig:pagerank-nosinks}, none of the nodes in the graph are sinks.

\subsection*{Accounting for Boredom} % ----------------------------------------

The model in \eqref{eq:pagerank-single-initial} assumes that the user can only click on links from their current page.
It is more realistic to assume that the user sometimes gets bored and randomly picks a new starting page.
Let $0\le\epsilon\le 1$, called the \emph{damping factor}, be the probability that a user stays interested at step $t$.
Then the probability that the user gets bored at any time (and then chooses a new random page) is $1-\epsilon$, and \eqref{eq:pagerank-single-initial} becomes
\begin{equation}
\label{eq:pagerank-single}
p_i(t+1) =
\underbrace{\epsilon\sum_{j=1}^{n}\left(\widetilde{A}_{ij}\frac{p_j(t)}{\sum_{k=1}^n \widetilde{A}_{kj}}\right)}_{\substack{\text{User stayed interested and}\\\text{clicked a link on the current page}}}
+ \underbrace{\vphantom{\sum_{j=1}^{n}\left(\frac{p_j(t)}{\sum_{k=1}^n \widetilde{A}_{kj}}\right)} \frac{1-\epsilon}{n}.}_{\substack{\text{User got bored and}\\\text{chose a random page}}}
\end{equation}
Note that \eqref{eq:pagerank-single} can be rewritten as the matrix equation
\begin{align}
\mathbf{p}(t+1) = \epsilon \widehat{A}\mathbf{p}(t) + \frac{1-\epsilon}{n}\mathbf{1},
\label{eq:pagerank-matrix}
\end{align}
where $\mathbf{p}(t)=[p_1(t), p_2(t), \ldots, p_n(t)]\trp$,
$\mathbf{1}$ is a vector of $n$ ones, and $\widehat{A}$ is the $n\times n$ matrix with entries
\begin{align}
\widehat{A}_{ij} = \frac{\widetilde{A}_{ij}}{\sum_{k=1}\widetilde{A}_{kj}}.
\label{eq:pagerank-Ahat-entries}
\end{align}
In other words, $\widehat{A}$ is $\widetilde{A}$ normalized so that the columns each sum to $1$.
For the graph in Figure \ref{fig:pagerank-nosinks}, the matrix $\widehat{A}$ is given by
\begin{align}
\widehat{A} = \begin{blockarray}{ccccccc}
& & \small\text{\textcolor{gray}{a}} & \small\text{\textcolor{gray}{b}} & \small\text{\textcolor{gray}{c}} & \small\text{\textcolor{gray}{d}} & \\
\begin{block}{c[cccccc]}
\small\text{\textcolor{gray}{a}} & & 0 & \textcolor{blue}{1/4} & 0 & 0 & \topstrut\\
\small\text{\textcolor{gray}{b}} & & 1/3 & \textcolor{blue}{1/4} & 1/2 & 0 & \\
\small\text{\textcolor{gray}{c}} & & 1/3 & \textcolor{blue}{1/4} & 0 & 1 & \\
\small\text{\textcolor{gray}{d}} & & 1/3 & \textcolor{blue}{1/4} & 1/2 & 0 & \botstrut\\
\end{block}\end{blockarray}.
\label{eq:pagerank-example-widehat}
\end{align}

\begin{problem} % Problem 1: DiGraph.__init__().
Write a class for representing directed graphs via their adjacency matrices.
The constructor should accept an $n\times n$ adjacency matrix $A$ and a list of node labels (such as $[$a, b, c, d$]$) defaulting to \li{None}.
Modify $A$ as in Figure \ref{fig:pagerank-nosinks} so that there are no sinks in the corresponding graph, then calculate the $\widehat{A}$ from \eqref{eq:pagerank-Ahat-entries}.
Save $\widehat{A}$ and the list of labels as attributes.
Use $[0,1,\ldots,n-1]$ as the labels if none are provided.
Finally, raise a \li{ValueError} if the number of labels is not equal to the number of nodes in the graph.
\\(Hint: use array broadcasting to compute $\widehat{A}$ efficiently.)

For the graph in Figure \ref{fig:pagerank-basic}, check that your $\widehat{A}$ matches \eqref{eq:pagerank-example-widehat}.
\label{prob:pagerank-init}
\end{problem}

\subsection*{Computing the Rankings} % ----------------------------------------

In the model \eqref{eq:pagerank-single}, define the \emph{rank} of node $i$ as the limit
\[
p_i = \lim_{t\to \infty} p_i(t).
\]
\begin{comment} % TODO: a note on Markov Chains, but not here.
For those familiar with Markov Chains, Equation \ref{eq:pagerank-matrix} defines a Markov chain.
Page ranks are simply the steady state of this Markov chain.
\end{comment}
There are several ways to solve for $\mathbf{p} = \lim_{t\rightarrow\infty} \mathbf{p}(t)$.

\subsubsection*{Linear System} % - - - - - - - - - - - - - - - - - - - - - - -

If $\mathbf{p}$ exists, then taking the limit as $t\rightarrow\infty$ to both sides of \eqref{eq:pagerank-matrix} gives the following.
\begin{align}
\nonumber
\lim_{t\rightarrow\infty}\mathbf{p}(t+1) &= \lim_{t\rightarrow\infty}\left[\epsilon \widehat{A}\mathbf{p}(t) + \frac{1-\epsilon}{n}\mathbf{1}\right] \\
\nonumber
\mathbf{p} &= \epsilon \widehat{A}\mathbf{p} + \frac{1-\epsilon}{n}\mathbf{1} \\
\label{eq:pagerank-algebraic}
\left(I - \epsilon \widehat{A}\right)\mathbf{p} &= \frac{1-\epsilon}{n}\mathbf{1}
\end{align}
This linear system is easy to solve as long as the number of nodes in the graph isn't too large.

\subsubsection*{Eigenvalue Problem} % - - - - - - - - - - - - - - - - - - - - -

Let $E$ be an $n \times n$ matrix of ones.
Then $E\mathbf{p}(t) = \mathbf{1}$ since $\sum_{i=1}p_i(t) = 1$.
Substituting into \eqref{eq:pagerank-matrix},
\begin{align}
\mathbf{p}(t+1)
= \epsilon \widehat{A}\mathbf{p}(t) + \frac{1-\epsilon}{n}E\mathbf{p}(t)
= \left(\epsilon \widehat{A} + \frac{1-\epsilon}{n}E\right)\mathbf{p}(t)
= B\mathbf{p}(t),
\label{eq:pagerank-eigenproblem}
\end{align}
where $B = \epsilon \widehat{A} + \frac{1-\epsilon}{n}E$.
Now taking the limit at $t\rightarrow\infty$ of both sides of \eqref{eq:pagerank-eigenproblem},
\begin{align*}
B\mathbf{p} = \mathbf{p}.
\end{align*}
That is, $\mathbf{p}$ is an eigenvector of $B$ corresponding to the eigenvalue $\lambda = 1$.
In fact, since the columns of $B$ sum to $1$, and because the entries of $B$ are strictly positive (because the entries of $E$ are all positive), Perron's theorem guarantees that $\lambda = 1$ is the unique eigenvalue of $B$ of largest magnitude, and that the corresponding eigenvector $\mathbf{p}$ is unique up to scaling.
Furthermore, $\mathbf{p}$ can be scaled so that each of its entires are positive, meaning $\mathbf{p}/\|\mathbf{p}\|_1$ is the desired PageRank vector.

\begin{info} % Side note: B defines a Markov chain.
A \emph{Markov chain} is a weighted directed graph where each node represents a \emph{state} of a discrete system.
The weight of the edge from node $j$ to node $i$ is the probability of transitioning from state $j$ to state $i$, and the adjacency matrix of a Markov chain is called a \emph{transition matrix}.

Since $B$ from \eqref{eq:pagerank-eigenproblem} contains nonnegative entries and its columns all sum to $1$, it can be viewed as the transition matrix of a Markov chain.
In that context, the limit vector $\mathbf{p}$ is called the \emph{steady state} of the Markov chain.
\end{info}

\subsubsection*{Iterative Method} % - - - - - - - - - - - - - - - - - - - - - -

Solving \eqref{eq:pagerank-algebraic} or \eqref{eq:pagerank-eigenproblem} is feasible for small networks, but they are not efficient strategies for very large systems.
The remaining option is to use an iterative technique.
Starting with an initial guess $\mathbf{p}(0)$, use  \eqref{eq:pagerank-matrix} to compute $\mathbf{p}(1),\mathbf{p}(2),\ldots$ until $\norm{\mathbf{p}(t)-\mathbf{p}(t-1)}$ is sufficiently small.
From \eqref{eq:pagerank-eigenproblem}, we can see that this is just the power method\footnote{See the Least Squares and Computing Eigenvalues lab for details on the power method.} for finding the eigenvector corresponding to the dominant eigenvalue of $B$.

\begin{problem} % Write methods for computing the PageRank vector.
Add the following methods to your class from Problem \ref{prob:pagerank-init}.
Each should accept a damping factor $\epsilon$ (defaulting to 0.85), compute the PageRank vector $\mathbf{p}$, and return a dictionary mapping label $i$ to its PageRank value $p_i$.

\begin{enumerate}
\item \li{linsolve()}: solve for $\mathbf{p}$ in \eqref{eq:pagerank-algebraic}.
\item \li{eigensolve()}: solve for $\mathbf{p}$ using \eqref{eq:pagerank-eigenproblem}.
Normalize the resulting eigenvector so its entries sum to $1$.
\item \li{itersolve()}: in addition to $\epsilon$, accept an integer \li{maxiter} and a float \li{tol}.
Iterate on \eqref{eq:pagerank-matrix} until $\|\mathbf{p}(t) - \mathbf{p}(t-1)\|_1 < $ \li{tol} or $t > $ \li{maxiter}.
Use $\mathbf{p}(0)=[\frac{1}{n},\frac{1}{n},\ldots,\frac{1}{n}]\trp$ as the initial vector (any positive vector that sums to $1$ will do, but this assumes equal starting probabilities).
\end{enumerate}
Check that each method yields the same results.
For the graph in Figure \ref{fig:pagerank-basic} with $\epsilon=0.85$, you should get the following dictionary mapping labels to PageRank values.
\begin{lstlisting}
<<{'a': 0.095758635, 'b': 0.274158285, 'c': 0.355924792, 'd': 0.274158285}>>
\end{lstlisting}
\label{prob:pagerank-computation}
\end{problem}

\begin{problem}
Write a function that accepts a dictionary mapping labels to PageRank values, like the outputs in Problem \ref{prob:pagerank-computation}.
Return a list of labels sorted \textbf{from highest to lowest} rank.
\\(Hint: if \li{d} is a dictionary, use \li{list(d.keys())} and \li{list(d.values())} to get the list of keys and values in the dictionary, respectively.)

For the graph in Figure \ref{fig:pagerank-basic} with $\epsilon=0.85$, this is the list $[$c, b, d, a$]$ (or $[$c, d, b, a$]$, since b and d have the same PageRank value).
\label{prob:pagerank-ranking}
\end{problem}

\begin{comment}
Looking at Figure \ref{fig:pagerank-nosinks}, it is easy to see why a has the lowest PageRank value: the only other node that points to it is b.
It also makes sense that c has the highest ranking, since c and d both have edges from the other three nodes pointing to them, but d only has one edge (pointing to c), while c points to both b and d.
In other words, at each step d distributes all of its importance to c, while c splits its importance between b and d.

Of course, constructing rankings is much more difficult to do by hand when there are more than just a few nodes in the graph.
\end{comment}

\begin{problem} % Rank webpages, subset of Stanford dataset.
The file \texttt{web\_stanford.txt} contains information on Stanford University webpages\footnote{\url{http://www.stanford.edu/}} and the hyperlinks between them, gathered in 2002.\footnote{See \url{http://snap.stanford.edu/data/web-Stanford.html} for the original (larger) dataset.}
Each line of the file is formatted as \li{a/b/c/d/e/f...}, meaning the webpage with ID \li{a} has hyperlinks to webpages with IDs \li{b}, \li{c}, \li{d}, and so on.

Write a function that accepts a damping factor $\epsilon$ defaulting to 0.85.
Read the data and get a list of the $n$ unique page IDs in the file (the labels).
Construct the $n\times n$ adjacency matrix of the graph where node $j$ points to node $i$ if webpage $j$ has a hyperlink to webpage $i$.
Use your class from Problem \ref{prob:pagerank-init} and its \li{itersolve()} method from Problem \ref{prob:pagerank-computation} to compute the PageRank values of the webpages, then rank them with your function from Problem \ref{prob:pagerank-ranking}.
Return the ranked list of webpage IDs.
\\(Hint: after constructing the list of webpage IDs, make a dictionary that maps a webpage ID to its index in the list.
For Figure \ref{fig:pagerank-basic}, this would be \li{\{'a': 0, 'b': 1, 'c': 2, 'd': 3\}}.
The values are the row/column indices in the adjacency matrix for each label.)

With $\epsilon=0.85$, the top three ranked webpage IDs are $98595$, $32791$, and $28392$.
\end{problem}

\section*{PageRank on Weighted Graphs} % ======================================

Nothing in the formulation of the PageRank model \eqref{eq:pagerank-matrix} requires that the edges of the graph are unweighted.
If $A_{ij}$ is the weight of the edge from node $j$ to node $i$ (weight $0$ meaning there is no edge from $j$ to $i$), then the columns of $\widehat{A}$ still sum to $1$.
Thus $B = \epsilon \widehat{A} + \frac{1-\epsilon}{n}E$ is still positive definite, so we can expect a unique PageRank vector $\mathbf{p}$ to exist.

Adding weights to the edges can improve the fidelity of the model and produce a slightly more realistic PageRank ordering.
On a given webpage, for example, if hyperlinks to page $a$ are clicked on more frequently hyperlinks to page $b$, the edge from node $a$ should be given more weight than the edge to node $b$.
% The actual weight doesn't matter as much how it relates to the weights of the other edges proceeding from the same node.

\begin{figure}[H] % directed network and adjacency matrix.
\captionsetup[subfigure]{justification=centering}
\centering
\begin{subfigure}{.45\textwidth}
\centering
\begin{tikzpicture}[normalcircle/.style={draw,circle,minimum size=.75cm,fill=none,thick,node distance=2.5cm}]
% Nodes
\node[normalcircle] (A) {a};
\node[normalcircle] (B) [above of=A,fill=blue!10] {b};
\node[normalcircle] (C) [right of=B] {c};
\node[normalcircle] (D) [below of=C] {d};
% Weighted Edges
\foreach \i/\j/\w in {A/B/2,A/D/1,C/D/1}
\draw[->,>=stealth',thick]  (\i) edge node [font=\normalsize,pos=.5,auto] {\w} (\j);
\draw[->,>=stealth',thick] (A) edge node [font=\normalsize,pos=.25,left] {1} (C);
\draw[->,>=stealth',thick] (C) edge node [font=\normalsize,pos=.5,above] {1} (B);
\draw[bend right=60,->,>=stealth',thick] (D) edge node [font=\normalsize,pos=.5,right] {2} (C);
\draw[bend right=60,->,>=stealth',thick,blue] (B) edge node [font=\normalsize,pos=.5,left] {2} (A);
\draw[->,>=stealth',thick,blue] (B) edge node [font=\normalsize,pos=.25,left] {2} (D);
\draw[bend left=60,->,>=stealth',thick,blue] (B) edge node [font=\normalsize,pos=.5,above] {1} (C);
\draw[thick,->,>=stealth',shorten >=1pt,blue] (B) to [out=110,in=170,loop,looseness=4.5] (B) node[xshift=-.3cm,yshift=.6cm] {1};
\end{tikzpicture}
\end{subfigure}
%
\begin{subfigure}{.45\textwidth}
\centering
\begin{align*}
&A = \begin{blockarray}{ccccccc}
& & \small\text{\textcolor{gray}{a}} & \small\text{\textcolor{gray}{b}} & \small\text{\textcolor{gray}{c}} & \small\text{\textcolor{gray}{d}} & \\
\begin{block}{c[cccccc]}
\small\text{\textcolor{gray}{a}} & & 0 & 0 & 0 & 0 & \topstrut\\
\small\text{\textcolor{gray}{b}} & & 2 & 0 & 1 & 0 & \\
\small\text{\textcolor{gray}{c}} & & 1 & 0 & 0 & 2 & \\
\small\text{\textcolor{gray}{d}} & & 1 & 0 & 2 & 0 & \botstrut\\
\end{block}\end{blockarray}
\\
&\widehat{A} = \begin{blockarray}{ccccccc}
& & \small\text{\textcolor{gray}{a}} & \small\text{b} & \small\text{\textcolor{gray}{c}} & \small\text{\textcolor{gray}{d}} & \\
\begin{block}{c[cccccc]}
\small\text{\textcolor{gray}{a}} & & 0 & \textcolor{blue}{1/4} & 0 & 0 & \topstrut\\
\small\text{\textcolor{gray}{b}} & & 1/2 & \textcolor{blue}{1/4} & 1/3 & 0 & \\
\small\text{\textcolor{gray}{c}} & & 1/4 & \textcolor{blue}{1/4} & 0 & 1 & \\
\small\text{\textcolor{gray}{d}} & & 1/4 & \textcolor{blue}{1/4} & 2/3 & 0 & \botstrut\\
\end{block}\end{blockarray}
\end{align*}
\end{subfigure}
\caption{A directed weighted graph with four nodes, together with its adjacency matrix and the corresponding PageRank transition matrix.
Edges that are added to fix sinks have weight $1$, so the computation of $\widetilde{A}$ and $\widehat{A}$ are exactly the same as in Figure \ref{fig:pagerank-nosinks} and \eqref{eq:pagerank-Ahat-entries}, respectively.
}
\label{fig:pagerank-weighted}
\end{figure}

\begin{problem} % NCAA March Madness ranking!
The files \texttt{ncaa2010.csv}, \texttt{ncaa2011.csv}, $\ldots$, \texttt{ncaa2017.csv} each contain data for men's college basketball for a given school year.\footnote{\texttt{ncaa2010.csv} has data for the 2010--2011 season, \texttt{ncaa2011.csv} for the 2011--2012 season, and so on.}
Each line (except the very first line, which is a header) represents a different basketball game, formatted \li{winning_team,losing_team}.%\footnote{There are no ties in basketball.}

Write a function that accepts a filename and a damping factor $\epsilon$ defaulting to 0.85.
Read the specified file (skipping the first line) and get a list of the $n$ unique teams in the file.
Construct the $n\times n$ adjacency matrix of the graph where node $j$ points to node $i$ with weight $w$ if team $j$ was defeated by team $i$ in $w$ games.
That is, \textbf{edges point from losers to winners}.
For instance, the graph in Figure \ref{fig:pagerank-weighted} would indicate that team c lost to team b once and to team d twice, team b was undefeated, and team a never won a game.
Use your class from Problem \ref{prob:pagerank-init} and its \li{itersolve()} method from Problem \ref{prob:pagerank-computation} to compute the PageRank values of the teams, then rank them with your function from Problem \ref{prob:pagerank-ranking}.
Return the ranked list of team names.

Using \texttt{ncaa2010.csv} with $\epsilon=0.85$, the top three ranked teams (of the $607$ total teams) should be UConn, Kentucky, and Louisville, in that order.
That season, UConn won the championship, Kentucky was a semifinalist, and Louisville lost in the first tournament round (a surprising upset).
\label{prob:pagerank-ncaa}
\end{problem}

\begin{info}
In Problem \ref{prob:pagerank-ncaa}, the damping factor $\epsilon$ acts as an ``upset'' factor: a larger $\epsilon$ puts more emphasis on win history; a smaller $\epsilon$ allows more randomness in the system, giving underdog teams a higher probability of defeating a team with a better record.

It is also worth noting that the sink-fixing procedure is still reasonable for this model because it gives every other team \textbf{equal} likelihood of beating an undefeated team.
That is, the additional edges don't provide an extra advantage to any one team.
% \footnote{The likelihood of a team being completely undefeated all season is extremely low; it's only happened $7$ times in history, and that was before the tournament was expanded to $64$ teams (cf. \url{https://www.thoughtco.com/basketballs-undefeated-teams-326279}).}
\end{info}

\subsection*{PageRank with NetworkX} % ----------------------------------------

\href{https://networkx.github.io/documentation/stable/}{NetworkX}, usually imported as \li{nx}, is a third-party package for working with networks.
It represents graphs internally with dictionaries, thus taking full advantage of the sparsity in a graph.
The base class for directed graphs is called \li{nx.DiGraph}.
Nodes and edges are usually added or removed incrementally with the following methods.

\begin{table}[H]
\centering
\begin{tabular}{r|l}
    Method & Description\\
    \hline
    \li{add_node()} & Add a single node.\\
    \li{add_nodes_from()} & Add a list of nodes.\\
    \li{add_edge()} & Add an edge between two nodes, adding the nodes if needed.\\
    \li{add_edges_from()} & Add multiple edges (and corresponding nodes as needed).\\
    \hline
    \li{remove_edge()} & Remove a single edge (no nodes are removed). \\
    \li{remove_edges_from()} & Remove multiple edges (no nodes are removed).\\
    \li{remove_node()} & Remove a single node and all adjacent edges.\\
    \li{remove_nodes_from()} & Remove multiple nodes and all adjacent edges. \\
\end{tabular}
\caption{Methods of the \li{nx.DiGraph} class for inserting or removing nodes and edges.}
\end{table}

For example, the weighted graph in Figure \ref{fig:pagerank-weighted} can be constructed with the following code.

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

# Initialize an empty directed graph.
>>> DG = nx.DiGraph()

# Add the directed edges (nodes are added automatically).
>>> DG.add_edge('a', 'b', weight=2)     # a --> b (adds nodes a and b)
>>> DG.add_edge('a', 'c', weight=1)     # a --> c (adds node c)
>>> DG.add_edge('a', 'd', weight=1)     # a --> d (adds node d)
>>> DG.add_edge('c', 'b', weight=1)     # c --> b
>>> DG.add_edge('c', 'd', weight=2)     # c --> d
>>> DG.add_edge('d', 'c', weight=2)     # d --> c
\end{lstlisting}

Once constructed, an \li{nx.Digrah} object can be queried for information about the nodes and edges.
It also supports dictionary-like indexing to access node and edge attributes, such as the weight of an edge.

\begin{table}[H]
\centering
\begin{tabular}{r|l}
    Method & Description\\
    \hline
    \li{has_node(A)} & Return \li{True} if \li{A} is a node in the graph.\\
    \li{has_edge(A,B)} & Return \li{True} if there is an edge from \li{A} to \li{B}.\\
    \li{edges()} & Iterate through the edges. \\
    \li{nodes()} & Iterate through the nodes. \\
    \li{number_of_nodes()} & Return the number of nodes.\\
    \li{number_of_edges()} & Return the number of edges.\\
\end{tabular}
\caption{Methods of the \li{nx.DiGraph} class for accessing nodes and edges.}
\end{table}

\begin{lstlisting}
# Check the nodes and edges.
>>> DG.has_node('a')
<<True>>
>>> DG.has_edge('b', 'a')
<<False>>
>>> list(DG.nodes())
<<['a', 'b', 'c', 'd']>>
>>> list(DG.edges())
<<[('a', 'b'), ('a', 'c'), ('a', 'd'), ('c', 'b'), ('c', 'd'), ('d', 'c')]>>

# Change the weight of the edge (a, b) to 3.
>>> DG['a']['b']["weight"] += 1
>>> DG['a']['b']["weight"]
3
\end{lstlisting}

NetworkX efficiently implements several graph algorithms.
The function \li{nx.pagerank()} computes the PageRank values of each node iteratively with sparse matrix operations.
This function returns a dictionary mapping nodes to PageRank values, like the methods in Problem \ref{prob:pagerank-computation}.

\begin{lstlisting}
# Calculate the PageRank values of the graph.
>>> nx.pagerank(DG, alpha=0.85)     # alpha is the damping factor (epsilon).
<<{'a': 0.08767781186947843,
 'b': 0.23613138394239835,
 'c': 0.3661321209576019,
 'd': 0.31005868323052127}>>
\end{lstlisting}

\begin{warn} % PageRanks sucks on directed networks.
NetworkX also has a class, \li{nx.Graph}, for \emph{undirected graphs}.
The edges in an undirected graph are bidirectional, so the corresponding adjacency matrix is symmetric.

The PageRank algorithm is not very useful for undirected graphs.
In fact, the PageRank value for node is close to its $degree$---the number of edges it connects to---divided by the total number of edges.
In Problem \ref{prob:pagerank-ncaa}, that would mean the team who simply played the most games would be ranked the highest.
Always use \li{nx.DiGraph}, not \li{nx.Graph}, for PageRank and other algorithms that rely on directed edges.
\end{warn}

\begin{problem} % Rank actors in the 250 most popular movies.
The file \texttt{top250movies.txt} contains data from the 250 top-rated movies according to IMDb.\footnote{\url{https://www.imdb.com/search/title?groups=top_250&sort=user_rating}}
Each line in the file lists a movie title and its cast as
\li{title/actor1/actor2/...},
with the actors listed mostly in billing order (stars first), though some casts are listed alphabetically or in order of appearance.

Create a \li{nx.DiGraph} object with a node for each actor in the file.
The weight from actor $a$ to actor $b$ should be the number of times that actor $a$ and $b$ were in a movie together but actor $b$ was listed first.
That is, \textbf{edges point to higher-billed actors} (see Figure \ref{fig:pagerank-actor-network}).
Compute the PageRank values of the actors and use your function from Problem \ref{prob:pagerank-ranking} to rank them.
Return the list of ranked actors.
\\(Hint: Consider using \li{itertools.combinations()} while constructing the graph.
Also, use \li{encoding="utf-8"} as an argument to \li{open()} to read the file, since several actors and actresses have nonstandard characters in their names such as {\o} and {\ae}.)

% Since this dataset only includes popular movies, and since edges point toward the stars of the movie, the PageRank vector can be seen as a way to determine who the most visible actors in Hollywood are.
With $\epsilon = 0.7$, the top three actors should be Leonardo DiCaprio, Robert De Niro, and Tom Hanks, in that order.
\label{prob:pagerank-actors}
\end{problem}

\begin{figure}[H]
\centering
\begin{tikzpicture}[thick]
% Nodes
\foreach [count=\i] \a/\t/\d in {0/Hugh\\Jackman/5, 1/Anne\\Hathaway/5, 2/Scarlett\\Johansson/5, 3/Christian\\Bale/5, 4/Michael\\Caine/5}
\draw (\a*360/5+18: \d cm) node[circle,draw=black,font=\sffamily\small,align=center,minimum size=1.75cm] (v\i)  {\t};
% Edges
\foreach \i/\j/\w in {3/1/1,4/1/1,3/5/1,5/2/2,5/4/4,2/4/1,3/4/1,5/1/1}
\draw[->,>=stealth',thick]  (v\i) edge node [font=\normalsize,pos=.5,auto] {\w} (v\j);
\end{tikzpicture}
\caption{A portion of the graph from Problem \ref{prob:pagerank-actors}.
Michael Caine was in four movies with Christian Bale where Christian Bale was listed first in the cast.}
\label{fig:pagerank-actor-network}
\end{figure}

\newpage

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

\subsection*{Sparsity} % ------------------------------------------------------

On very large networks, the PageRank algorithm becomes computationally difficult because of the size of the adjacency matrix $A$.
Fortunately, most adjacency matrices are highly sparse, meaning the number of edges is much lower than the number of entries in the matrix.
Consider adding functionality to your class from Problem \ref{prob:pagerank-init} so that it stores $\widehat{A}$ as a sparse matrix and performs sparse linear algebra operations in the methods from Problem \ref{prob:pagerank-computation} (use \li{scipy.sparse.linalg}).

\subsection*{PageRank as a Predictive Model} % --------------------------------

The data files in Problem \ref{prob:pagerank-ncaa} include tournament games for their respective seasons, so the resulting rankings naturally align with the outcome of the championship.
However, it is also useful to use PageRank as a predictive model: given data for all regular season games, can the outcomes of the tournament games be predicted?
Over $40$ million Americans fill out $60$--$100$ million March Madness brackets each year and bet over $\$9$ billion on the tournament, so being able to predict the outcomes of the games is a big deal.
See \url{http://games.espn.com/tournament-challenge-bracket} for more details.

Given regular season data, PageRank can be used to predict tournament results as in Problem \ref{prob:pagerank-ncaa}.
There are some pitfalls though; for example, how should $\epsilon$ be chosen?
Using $\epsilon = .5$ with \texttt{ncaa2010.csv} minus tournament data (all but the last 63 games in the file) puts UConn---the actual winner that year---in seventh place, while $\epsilon = .9$ puts UConn in fourth.
Both values for $\epsilon$ also rank BYU as number one, but BYU lost in the Sweet Sixteen that year.
In practice, Google uses $.85$ as the damping factor, but there is no rigorous reasoning behind that particular choice.

\subsection*{Other Centrality Measures} % -------------------------------------

In network theory, the \emph{centrality} of a node refers to its importance.
Since there are lots of ways to measure importance, there are several different centrality measures.

\begin{itemize}
\item \emph{Degree centrality} uses the \emph{degree} of a node, meaning the number of edges adjacent to it (independent of edge direction), for ranking.
An academic paper that has been cited many times has a high degree and is considered more important than a paper that has only been cited once.
\item \emph{Eigenvector centrality} is an extension of degree centrality.
Instead of each neighbor contributing equally to the centrality, nodes that are important are given a higher weight.
Thus a node connected to lots of unimportant nodes can have the same measure as a node connected to a few, important nodes.
Eigenvector centrality is measured by the eigenvector associated with the largest eigenvalue of the adjacency matrix of the network.
% One example of this is a social network where one person may be connected to a few famous people.
\item \emph{Katz centrality} is a modification to eigenvalue centrality for directed networks.
Outgoing nodes contribute centrality to their neighbors, so an important node makes its neighbors more important.
\item PageRank adapts Katz centrality by averaging out the centrality that a node can pass to its neighbors.
For example, if Google---a website that should have high centrality---points to a million websites, then it shouldn't pass on that high centrality to all of million of its neighbors, so each neighbor gets one millionth of Google's centrality.
\end{itemize}

For more information on these centralities, as well as other ways to measure node importance, see \cite{newman2010networks}.