\documentclass[10pt]{beamer}

\usepackage[spanish,activeacute]{babel}
\usepackage[utf8x]{inputenc}
\usepackage{eurosym}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{graphicx}
\usepackage{lmodern}
\usepackage{enumerate}

\def\X{\ve{X}}
\def\x{\ve{x}}
\newcommand{\p}[1]{p_{_{#1}}} %pdf or pmf

\definecolor{darkblue}{rgb}{0.0, 0.0, 0.55}
\setbeamercolor{title}{fg=darkblue}
\setbeamercolor{frametitle}{fg=darkblue}
\newcommand{\myitem}{\item[$\bullet$]}
\definecolor{darkgreen}{rgb}{0, 0.55, 0}
\definecolor{darkred}{rgb}{0.55, 0,0}

\usepackage{tikz}
\usetikzlibrary{fit,positioning}
\usetikzlibrary{shapes,matrix,decorations.markings,arrows}
\usetikzlibrary{graphs}
\newcommand{\ve}[1]{\boldsymbol{#1}}
\newcommand{\set}[1]{\mathcal{#1}}
    \usetikzlibrary{chains,positioning}
    \usepackage{mathtools}

\newcommand{\noteB}[1]{\textbf{\textcolor{darkblue}{#1}}}

\newcommand{\noteR}[1]{\textbf{\textcolor{darkred}{#1}}}

\newcommand{\noteG}[1]{\textbf{\textcolor{darkgreen}{#1}}}

\newcommand{\mes}[2]{m_{#1\rightarrow#2}}
\newcommand{\logmes}[2]{l_{#1\rightarrow#2}}
\newcommand{\Iset}[1]{\mathtt{#1}} %Index set

\setbeamertemplate{navigation symbols}{\usebeamerfont{footline} \insertframenumber/\inserttotalframenumber}
\logo{\includegraphics[scale=0.04]{logouc3m.eps}}

\title{Inference in Bayesian Networks}
\author{Pablo M. Olmos, olmos@tsc.uc3m.es}
\date{Course on Bayesian Networks,  November 2016}

%\AtBeginSection{\frame{\tableofcontents[currentsection]}}
\AtBeginSection{\frame{\sectionpage}}
%\AtBeginSubsection{\frame{\subsectionpage}}
\AtBeginSubsection{\frame{\frametitle{Bayessian Networks}\tableofcontents[currentsection,currentsubsection]}}

\begin{document}

\frame{\titlepage}

\begin{frame}{Index}
\tableofcontents
\end{frame}

\section{Discrete Inference using Belief Propagation}

\begin{frame}{Discrete Inference}

\begin{itemize}
\item Let $X_j\in\set{X}$, $j=1,\ldots,5$, be discrete R.V., where $K\doteq|\set{X}|$
\item Consider the following BN:
\end{itemize}
\begin{align*}
p(\x)=p(x_1)p(x_2|x_1)p(x_4)p(x_3|x_2,x_4)p(x_5|x_4)p(x_6|x_2)
\end{align*}

\begin{figure}
\centering
\begin{tikzpicture}[scale=0.8]
\tikzstyle{factor}=[rectangle,minimum size = 3mm, thick, draw =black,fill=black]
\tikzstyle{var}=[circle,minimum size = 3mm, thick, draw =black,fill=black]
\tikzstyle{var2}=[circle, thick, draw =black]
\tikzstyle{second}=[circle, minimum size = 10mm, thick]
\tikzstyle{box}=[rectangle, draw=black!100]
\tikzstyle{connect}=[-latex, thick]
\tikzstyle{arrow}=[draw, -latex]

\draw[step=5cm];
	\node[var2] (x_1) at (-1,0) []{$x_1$};
	\node[var2] (x_2) at (1,0) []{$x_2$};
	\node[var2] (x_3) at (3,0) []{$x_3$};
	\node[var2] (x_4) at (3,-2) []{$x_4$};
	\node[var2] (x_5) at (5,-2) []{$x_5$};
	\node[var2] (x_6) at (1,-2) []{$x_6$};

	\path [arrow]
		(x_1) edge []  (x_2)
		(x_2) edge []  (x_3)
		(x_2) edge []  (x_6)
		(x_4) edge []  (x_3)
		(x_4) edge []  (x_5);

\end{tikzpicture}
\end{figure}

\begin{itemize}
\item \textcolor{darkred}{\textbf{Inference}}: evaluate the probability distribution over some set of variables, given the
values of another set of variables.
\end{itemize}

\end{frame}

\begin{frame}{Brute-force Inference}
\begin{align*}
p(\x)=p(x_1)p(x_2|x_1)p(x_4)p(x_3|x_2,x_4)p(x_5|x_4)p(x_6|x_2)
\end{align*}
\begin{itemize}
\item Assume each variable is binary, i.e., $\set{X}=\{0,1\}$.
\item For example, how can we compute $p(x_2|x_1=0)$?
\end{itemize}

\vspace{0.5cm}
\textbf{\textcolor{darkred}{Naive approach}}:
\begin{align*}
p(x_1=0,x_2)&=\sum_{x_3,x_4,x_5,x_6} p(x_1=0,x_2,x_3,x_4,x_5,x_6) \qquad \color{darkred}{[\text{32 terms}]}\\
p(x_1=0)&=\sum_{x_2} p(x_1=0,x_2) \qquad \color{darkred}{[\text{2 terms}]} \\
p(x_2|x_1=0)&=\frac{p(x_1=0,x_2)}{p(x_1=0)} \qquad \color{darkred}{[\text{2 terms}]}
\end{align*}

\textcolor{darkblue}{The naive approach for discrete inference for $n$ R.V. each taking $K$ possible values  has complexity $\mathcal{O}\left(K^n\right)$.}

\end{frame}

\begin{frame}{A more efficient approach}
\begin{align*}
p(\x)=p(x_1)p(x_2|x_1)p(x_4)p(x_3|x_2,x_4)p(x_5|x_4)p(x_6|x_2)
\end{align*}

The \textcolor{darkgreen}{Variable Elimination} method exploits the factorization of $p(\x)$ and distributive law to efficiently compute marginals.
\begin{align*}
&p(x_1=0,x_2)=\sum_{x_3,x_4,x_5,x_6} p(x_1=0,x_2,x_3,x_4,x_5,x_6)\\
&=p(x_1=0)p(x_2|x_1=0)\left(\sum_{x_6} p(x_6|x_2)\right) \left(\sum_{x_3,x_4} p(x_4)p(x_3|x_2,x_4) \sum_{x_5} p(x_5|x_4) \right)
\\
&=p(x_1=0)p(x_2|x_1=0)\underbrace{\sum_{x_3,x_4} p(x_4)p(x_3|x_2,x_4)}_{f(x_2)} \qquad \color{darkred}{[\text{8 terms}]}
\end{align*}
\end{frame}

\begin{frame}{Re-using computations}
\begin{align*}
p(\x)=p(x_1)p(x_2|x_1)p(x_4)p(x_3|x_2,x_4)p(x_5|x_4)p(x_6|x_2)
\end{align*}
\begin{itemize}
\item Imagine we are also interested in computing $p(x_1=0,x_6)$.
\end{itemize}
\begin{align*}
&p(x_1=0,x_6)=\sum_{x_2,x_3,x_4,x_5} p(x_1=0,x_2,x_3,x_4,x_5,x_6)\\
&=p(x_1=0)\sum_{x_2}p(x_6|x_2) p(x_2|x_1=0) \underbrace{\left(\sum_{x_3,x_4} p(x_4)p(x_3|x_2,x_4)\right)}_{f(x_2) }
\end{align*}
\begin{itemize}
\item Storing Intermediate computations (such as $f(x_2)$) makes infernce very efficient if multiple queries are made over $p(\x)$.
\item \textcolor{darkblue}{Belief Propagation}!
\end{itemize}
\end{frame}

\begin{frame}{Factor graphs}
\begin{itemize}
\item In inference,  it’s often easier to convert directed and
undirected graphs into factor graphs.
\end{itemize}
\begin{align*}
p(\x)&=p(x_1)p(x_2|x_1)p(x_4)p(x_3|x_2,x_4)p(x_5|x_4)p(x_6|x_2)\\
&=t_1(x_1)t_2(x_1,x_2)t_3(x_2,x_3,x_4)t_4(x_4)t_5(x_4,x_5)t_6(x_2,x_6)
\end{align*}

\begin{figure}
\centering
\begin{tikzpicture}[scale=0.8]
\tikzstyle{factor}=[rectangle,minimum size = 3mm, thick, draw =black,fill=black]
\tikzstyle{var}=[circle,minimum size = 3mm, thick, draw =black,fill=black]
\tikzstyle{second}=[circle, minimum size = 10mm, thick]
\tikzstyle{box}=[rectangle, draw=black!100]
\tikzstyle{connect}=[-latex, thick]
\draw[step=5cm];

	\node[factor] (t_1) at (-2,0) [label=above:{$t_1$}]{};
	\node[var] (x_1) at (-1,0) [label=above:{$x_1$}]{};
	\node[factor] (t_2) at (0,0) [label=above:{$t_2$}]{};
	\node[var] (x_2) at (1,0) [label=above:{$x_2$}]{};
	\node[factor] (t_3) at (2,0) [label=above:{$t_3$}]{};
	\node[var] (x_3) at (3,1) [label=above:{$x_3$}]{};
	\node[factor] (t_4) at (3,-2) [label=below:{$t_4$}]{};
	\node[var] (x_4) at (3,-1) [label=left:{$x_4$}]{};
	\node[factor] (t_5) at (4,-1) [label=below:{$t_5$}]{};
	\node[var] (x_5) at (5,-1) [label=right:{$x_5$}]{};
	\node[factor] (t_6) at (1,-1) [label=left:{$t_6$}]{};
	\node[var] (x_6) at (1,-2) [label=below:{$x_6$}]{};

%     \node[] () at (7,1) [label=right:{$\Iset{Ne}(X_4)=\{2,4,5\}$}]{};
%	\node[] () at (7,-1) [label=right:{$\Iset{Ne}(t_2)=\{2,4,3\}$}]{};

	\path
		(t_1) edge []  (t_3)
		(x_2) edge [] (x_6)
		(t_3) edge [] (x_3)
		(t_3) edge [] (x_4)
		(x_4) edge [] (t_4)
		(x_4) edge [] (x_5);

\end{tikzpicture}
\end{figure}

\begin{itemize}
\item \textcolor{darkblue}{Variables nodes}: we draw  circles for each variable $X_i$ in the distribution.
\item \textcolor{darkblue}{Factor nodes}: we draw filled dots for each factor $t_j$ in the distribution.
\end{itemize}

\end{frame}

\begin{frame}{Belief Propagation (I)}
\begin{itemize}
\item Local computations are regarded as \emph{messages}  between the nodes in the factor graph.
\item Iterative message-passing algorithm.
\item \noteB{$\mes{x_i}{t_j}(x_i)$} denotes the message sent from node $X_i$ to factor node $t_j$.
\item \noteB{$\mes{t_j}{x_i}(x_i)$} denotes the message sent from factor node $t_j$ to variable node $X_i$.
\item Both  messages are indeed functions of $X_i$, namely each message is a stored table of $|\set{X}|$ values.
\item At each iteration, messages are updated following simple \noteB{update rules} according to a valid \noteG{schedule}.
\end{itemize}

\end{frame}

\frame{
\frametitle{Update rules (I)}
\begin{tikzpicture}[scale=0.7]
\tikzstyle{factor}=[rectangle,minimum size = 3mm, thick, draw =black, node distance = 16mm,fill=black]
\tikzstyle{var}=[circle,minimum size = 3mm, thick, draw =black, node distance = 16mm,fill=black]
\tikzstyle{second}=[circle, minimum size = 10mm, thick, node distance = 5mm]
\tikzstyle{box}=[rectangle, draw=black!100]
\tikzstyle{connect}=[-latex, thick]
\node[second] at (-6,2) [label=center:{\textbf{Variable-to-factor message}}]{};
\node[second] at (-6,0) [label=center:{$\displaystyle\mes{x_i}{t_j}(x_i)=\prod_{\substack{k\in\Iset{Ne}(X_i) \\ k\neq j}}\mes{t_k}{x_i}(x_i)$}]{};
%\node[second] at (-6,-2) [label=center:{\color{darkred}{$|\Iset{Ne}(X_i)|\times |\set{X}|$ pointwise multiplications}}]{};

\node[factor] (t_1) at (1,2) [label=above:$t_1$]{};
\node[factor] (t_2) at (0,0) [label=above:$t_2$]{};
\node[factor] (t_3) at (1,-2) [label=above:$t_3$]{};
\node[var] (x_i) at (2.5,0) [label=above:$X_i$]{};
\node[factor] (t_j) at (5,0) [label=above: $t_j$]{};
\node[second] (m1i) at (1,1.25) [label=right: $\mes{t_1}{x_i}$]{};
\node[second] (m2i) at (1,-1.25) [label=right: $\mes{t_3}{x_i}$]{};
\node[second] (m3i) at (-0.5,0.2) [label=right: $\mes{t_2}{x_i}$]{};
\node[second] (m4i) at (2,0.2) [label=right: $\mes{x_i}{t_j}$]{};

\path
	(t_1) edge (x_i)
	(t_2) edge (x_i)
	(t_3) edge (x_i)
	(x_i) edge (t_j);
%
%\node[second] at (-6,-4) [label=center:{\textcontinuedbf{Factor-to-variable message}}]{};
%\node[second] at (-6,-6) [label=center:{$\displaystyle\mes{t_j}{x_i}(x_i)=\sum_{\x_{j}\sim x_i}~ t_j(\x_{j})\prod_{\substack{m\in \Iset{Ne}(t_j) \\ m\neq i}}\mes{x_m}{t_j}(x_m)$}]{};
%%\node[second] at (-6,-8) [label=center:{\color{darkred}{$|\Iset{Ne}(X_i)|\times |\set{X}|$ pointwise multiplications}}]{};
%%\node[second] at (-6,-8) [label=center:{\color{darkred}{$|\Iset{Ne}(X_i)|^|\set{X}|$ additions}}]{};
%\node[var] (t_12) at (1,-4) [label=above:$X_1$]{};
%\node[var] (t_22) at (0,-6) [label=above:$X_2$]{};
%\node[var] (t_32) at (1,-8) [label=above:$X_3$]{};
%\node[factor] (x_i2) at (2.5,-6) [label=above:$t_j$]{};
%\node[var] (t_j2) at (5,-6) [label=above: $X_i$]{};
%\node[second] (m1i) at (1,-4.75) [label=right: $\mes{x_1}{t_j}$]{};
%\node[second] (m2i) at (1,-7.25) [label=right: $\mes{x_3}{t_j}$]{};
%\node[second] (m3i) at (-0.5,-5.8) [label=right: $\mes{x_2}{t_j}$]{};
%\node[second] (m4i) at (2,-5.8) [label=right: $\mes{t_j}{x_i}$]{};
%
%\path
%	(t_12) edge (x_i2)
%	(t_22) edge (x_i2)
%	(t_32) edge (x_i2)
%	(x_i2) edge (t_j2);

\end{tikzpicture}

\vspace{1cm}
\noteR{At variable nodes we simply multiply incomming messages}.

}

\frame{
\frametitle{Update rules (II)}
\begin{tikzpicture}[scale=0.7]
\tikzstyle{factor}=[rectangle,minimum size = 3mm, thick, draw =black, node distance = 16mm,fill=black]
\tikzstyle{var}=[circle,minimum size = 3mm, thick, draw =black, node distance = 16mm,fill=black]
\tikzstyle{second}=[circle, minimum size = 10mm, thick, node distance = 5mm]
\tikzstyle{box}=[rectangle, draw=black!100]
\tikzstyle{connect}=[-latex, thick]

\node[second] at (-7,-4) [label=center:{\textbf{Factor-to-variable message}}]{};
\node[second] at (-6,-6) [label=center:{$\displaystyle\mes{t_j}{x_i}(x_i)=\sum_{\x_{j}\sim x_i}~ t_j(\x_{j})\prod_{\substack{m\in \Iset{Ne}(t_j) \\ m\neq i}}\mes{x_m}{t_j}(x_m)$}]{};
%\node[second] at (-6,-8) [label=center:{\color{darkred}{$|\Iset{Ne}(X_i)|\times |\set{X}|$ pointwise multiplications}}]{};
%\node[second] at (-6,-8) [label=center:{\color{darkred}{$|\Iset{Ne}(X_i)|^|\set{X}|$ additions}}]{};
\node[var] (t_12) at (1,-4) [label=above:$X_1$]{};
\node[var] (t_22) at (0,-6) [label=above:$X_2$]{};
\node[var] (t_32) at (1,-8) [label=above:$X_3$]{};
\node[factor] (x_i2) at (2.5,-6) [label=above:$t_j$]{};
\node[var] (t_j2) at (5,-6) [label=above: $X_i$]{};
\node[second] (m1i) at (1,-4.75) [label=right: $\mes{x_1}{t_j}$]{};
\node[second] (m2i) at (1,-7.25) [label=right: $\mes{x_3}{t_j}$]{};
\node[second] (m3i) at (-0.5,-5.8) [label=right: $\mes{x_2}{t_j}$]{};
\node[second] (m4i) at (2,-5.8) [label=right: $\mes{t_j}{x_i}$]{};

\path
	(t_12) edge (x_i2)
	(t_22) edge (x_i2)
	(t_32) edge (x_i2)
	(x_i2) edge (t_j2);

\end{tikzpicture}

\vspace{1cm}
\noteR{At factor nodes we perform local marginalization}.

}

\begin{frame}{Belief Propagation (II)}

If factor graph is \noteB{cycle-free}:
\begin{itemize}
\item \noteG{Convergence guaranteed} after a few iterations.
\item Upon convergence, variable marginals can be computed by multiplying incoming messages and normalize:
\begin{align*}
\p{X_i}(x_i)=\frac{1}{Z_i}\prod_{k\in\Iset{Ne}(X_i)}\mes{t_k}{x_i}(x_i),
\end{align*}
where the normalization constant is trivially obtained using the fact that the marginal must sum up to 1.
\end{itemize}

%If factor graph is \noteR{contains cycles}:
%\begin{itemize}
%\item Loopy Belief Propagation: run propagation as if graph is simply connected.
%\item \noteG{Convergence not guaranteed} in general.
%\item Approximate results! Often works well in practice unless the graph is not very dense.
%\item Exact Inference is possible by transforming the graph into a cycle-free graph (E.g. by clustering variable nodes). \noteG{Junction Tree algorithm!}
%\end{itemize}

\end{frame}

\begin{frame}{Belief Propagation (III)}
%
%If factor graph is \noteB{cycle-free}:
%\begin{itemize}
%\item \noteG{Convergence guaranteed} after a few iterations.
%\item Upon convergence, variable marginals can be computed by multiplying incoming messages and normalize:
%\begin{align*}
%\p{X_i}(x_i)=\frac{1}{Z_i}\prod_{k\in\Iset{Ne}(X_i)}\mes{t_k}{x_i}(x_i),
%\end{align*}
%where the normalization constant is trivially obtained using the fact that the marginal must sum up to 1.
%\end{itemize}

If factor graph is \noteR{contains cycles}:
\begin{itemize}
\item Loopy Belief Propagation: run propagation as if graph is simply connected.
\item \noteG{Convergence not guaranteed} in general.
\item Approximate results! Often works well in practice, unless the graph is very dense.
\item Exact Inference is possible by transforming the graph into a cycle-free graph (E.g. by clustering variable nodes). \noteG{Junction Tree algorithm!}
\item JTE complexity is in general very high unless the graph structure is very regular (e.g. computer vision applications).
\end{itemize}

\end{frame}

\begin{frame}{Belief Propagation (IV)}

Computing/estimating joint marginals $p(x_i,\x_{\text{pa}_i})$ from BP messages:
\begin{itemize}
\item Multiply the factor $p(x_i|\x_{\text{pa}_i})$ by all those messages coming to the cluster $(x_i,\x_{\text{pa}_i})$ from the \noteR{rest of the factor graph}
\end{itemize}

\begin{figure}
\centering
\begin{tikzpicture}[scale=0.8]
\tikzstyle{factor}=[rectangle,minimum size = 3mm, thick, draw =black,fill=black]
\tikzstyle{factor3}=[rectangle,minimum size = 3mm, thick, draw =darkgreen,fill=darkgreen]
\tikzstyle{var}=[circle,minimum size = 3mm, thick, draw =black,fill=black]
\tikzstyle{var3}=[circle,minimum size = 3mm, thick, draw =darkgreen,fill=darkgreen]
\tikzstyle{second}=[circle, minimum size = 10mm, thick]
\tikzstyle{box}=[rectangle, draw=black!100]
\tikzstyle{connect}=[-latex, thick]
\draw[step=5cm];

	\node[factor] (t_1) at (-2,0) [label=above:{$t_1$}]{};
	\node[var] (x_1) at (-1,0) [label=above:{$x_1$}]{};
	\node[factor] (t_2) at (0,0) [label=above:{$t_2$}]{};
	\node[var3] (x_2) at (1,0) [label=above:{$x_2$}]{};
	\node[factor3] (t_3) at (2,0) [label=above:{$t_3$}]{};
	\node[var3] (x_3) at (3,1) [label=above:{$x_3$}]{};
	\node[factor] (t_4) at (3,-2) [label=below:{$t_4$}]{};
	\node[var3] (x_4) at (3,-1) [label=left:{$x_4$}]{};
	\node[factor] (t_5) at (4,-1) [label=below:{$t_5$}]{};
	\node[var] (x_5) at (5,-1) [label=right:{$x_5$}]{};
	\node[factor] (t_6) at (1,-1) [label=left:{$t_6$}]{};
	\node[var] (x_6) at (1,-2) [label=below:{$x_6$}]{};

      \node[] (x_22) at (0.9,0.1) []{};
      \node[] (t_22) at (0.1,0.1) []{};
      \node[] (x_23) at (0.9,-0.1) []{};
      \node[] (t_62) at (0.9,-1+0.1) []{};

      \node[] (x_42) at (3.1,-0.9) []{};
      \node[] (x_43) at (3.1,-1.1) []{};
       \node[] (t_52) at (3.9,-1+0.1) []{};
	\node[] (t_42) at (3.1,-2+0.1) []{};

	 \node[] (x_24) at (1.1,0.1) []{};
	 \node[] (t_32) at (1.9,0.1) []{};
	 \node[] (x_44) at (2.9,-0.7) []{};
	 \node[] (t_33) at (2.3,-0.1) []{};

	\path
		(t_1) edge []  (x_2)
		(x_2) edge [] (t_3)
		(x_2) edge [] (x_6)
		(t_3) edge [] (x_3)
		(t_3) edge [] (x_4)
		(x_4) edge [] (t_4)
		(x_4) edge [] (x_5);

	\draw[->,darkgreen,thick]      (t_22) to[]      (x_22);
	\draw[->,darkgreen,thick]      (t_62) to[]      (x_23);
	\draw[->,darkgreen,thick]      (t_42) to[]      (x_43);
	\draw[->,darkgreen,thick]      (t_52) to[]      (x_42);
	\draw[->,darkblue,thick]      (x_24) to[]      (t_32);
	\draw[->,darkblue,thick]      (x_44) to[]      (t_33);

\end{tikzpicture}
\end{figure}

\begin{align*}
p(x_2,x_3,x_4)&\propto t_3(x_2,x_3,x_4) \color{darkgreen}{\mes{t_2}{x_2}(x_2)\mes{t_6}{x_2}(x_2)\mes{t_4}{x_4}(x_4)\mes{t_5}{x_4}(x_4)}\\
&=t_3(x_2,x_3,x_4)\color{darkblue}{\mes{x_2}{t_3}(x_3)\mes{x_4}{t_3}(x_4)}
\end{align*}

\end{frame}

\section{Inference in Gaussian Linear BNs}

\frame{
\frametitle{Gaussian Linear BNs}

\begin{itemize}
\item Let $X_i$, $i=1,\ldots,n$, be real-valued R.Vs. such that
\begin{align*}
X_i=\sum_{k\in\text{pa}_i}b_{ki}(X_k-\mu_k)+c_i,
\end{align*}
 where $c_i\sim\mathcal{N}(\mu_i,\sigma^2_i)$, $i=1,\ldots,n$, are independent R.V.
\item $\X=\ve{B}(\X-\ve{\mu})+\ve{c}$, where $\ve{B}_{n \times n}$ can always be re-arranged to be upper-triangular (otherwise graph is not DAG).
 \item In other words,
\begin{align*}
X_i|\x_{\text{pa}_i}&\sim \mathcal{N}(m_i,\sigma^2_i), \qquad m_i=\mu_i+\sum_{k\in\text{pa}_i}b_{ki}(x_k-\mu_k)
\end{align*}
\end{itemize}
}

\frame{
\frametitle{Exact Inference in Linear BNs}
\begin{itemize}
\item $\X\sim\mathcal{N}(\ve{\mu},\ve{\Sigma})$, where
\begin{align*}
\ve{\Sigma}=\mathbb{E}[(\X-\ve{\mu})^T(\X-\ve{\mu})]=(\ve{I}-\ve{B}^T)^{-1}\ve{D}(\ve{I}-\ve{B})^{-1}
\end{align*}
and $\ve{D}=\text{diag}(\sigma^2_i)$.
\end{itemize}
\begin{itemize}
\item \noteR{Naive approach}: $(\ve{I}-\ve{B}^T)^{-1}$ $\rightarrow \mathcal{O}(n^3)$ complexity.
\end{itemize}
\begin{itemize}
\item \noteG{Gaussian Belief Propagation}: $\rightarrow \mathcal{O}(n^3_{\text{max}})$ complexity, where $n_{\text{max}}$ is the maximum number of variables connected to a factor node in the factor graph representation of $p(\x)$.
\end{itemize}
}

\frame{
\frametitle{Gaussian Linear BNs}

\begin{itemize}
\item Sometimes a slightly different model is used. For $i=1,\ldots,n$ we have
\begin{align*}
X_i=\sum_{k\in\text{pa}_i}b_{ki}X_k+c_i
\end{align*}
\item $\X=\ve{B}\X+\ve{c}$
\item $\X\sim\mathcal{N}(\ve{\mu},\ve{\Sigma})$, with the same covariance matrix:
\begin{align*}
\ve{\Sigma}=\mathbb{E}[(\X-\ve{\mu})^T(\X-\ve{\mu})]=(\ve{I}-\ve{B}^T)^{-1}\ve{D}(\ve{I}-\ve{B})^{-1}
\end{align*}
\item To compute the mean elements $a_i$, $i=1,\ldots,n$, we need to trasverse the graph in topological order (from parents to child nodes). Assuming $a_k$ for $k\in\text{pa}_i$ have been computed, then
\begin{align*}
a_i=\mu_i+\sum_{k\in\text{pa}_i}b_{ki}a_{k}
\end{align*}
\end{itemize}

}

\frame{
\frametitle{Hybrid discrete \& Gaussian Linear BNs}

\begin{itemize}
\item Certain class of probabilistic models containing both continuous and discrete R.V. where exact inference is analytically tractable.
\item Assume we have $n$ real-valued nodes $X_i$ such that
\begin{align*}
X_i=\sum_{k\in\text{pa}_i}b_{ki}(Z_i)X_k+c_i,
\end{align*}
where both $b_{ki}(Z_i)$ and  $c_i\sim \mathcal{N}\left(\mu_i(Z_i),\sigma^2_i(Z_i)\right)$ depend on  $Z_i$ \noteG{a discrete R.V.}.
\item Inference is exact, we essentially average over a mixture of Gaussian terms, each given by a certain configuration of the vector $\ve{z}$.  \noteR{Number of terms in the mixture grows exponentially fast with $n$ in the general case.}
\item \noteG{Good reference:} \emph{Inference and Learning in Hybrid Bayessian Networks}, Kevin P. Murphy, Report, 1998 (public online).
\end{itemize}
}

\frame{
\frametitle{Inference in Hidden markov models and Linear Gaussian state-space models}

\begin{figure}
\begin{tabular}{c}
\includegraphics[scale=0.6]{HMM.pdf}
\end{tabular}
\end{figure}

\begin{itemize}
\item Time-Series (speech processing, tracking, ...)
\item In HMMs, the states $X_t$ are discrete.
\item In linear Gaussian SSMs, the states are real Gaussian vectors.
\item Both HMMs and SSMs can be represented as singly connected DAGs.
\item The forward–backward algorithm in hidden Markov models (HMMs), and the
Kalman smoothing algorithm in SSMs are both instances of belief propagation.
\end{itemize}

}

\section{Approximate Inference}

\begin{frame}{Approximate Inference}
\begin{itemize}
\item Few representative cases where exact inference is possible. Yet it can be very slow.
\begin{itemize}
\item Discrete inference is always possible (just performing sums), but the Junction Tree Algorithm can be cumbersome.
\end{itemize}
\item In many other scenarios, exact inference is not even possible. We must therefore resort to \noteG{approximation techniques}.
\begin{enumerate}
\item Variational methods \& Mean Field approximations.
\item Loopy Belief Propagation, Approximate Message Passing, Expectation Propagation.
\item Sampling (Monte Carlo) methods. Importance Sampling.
\item Monte Carlo Markov Chain (MCMC), and includes as special cases Gibbs sampling and the Metropolis-Hasting algorithm.
\end{enumerate}
\item Approximate Inference is  \noteR{a huge topic}: see the references for more details.
\end{itemize}
\end{frame}

\section{References}
\frame{
\frametitle{References}
\noteB{Books}
\begin{itemize}
\item  Christopher M. Bishop, Pattern Recognition and Machine Learning, Ed. Springer. Chapters 8-11.
\item David Barber, Bayesian Reasoning and Machine Learning. Chapters 1-7.
\item Kevin P. Murphy, Machine Learning: A Probabilistic Perspective. Chapters 10, 11, 18-24.
\end{itemize}

\noteG{Articles}:
\begin{itemize}
\item  Kevin P. Murphy, A Brief Introduction to Graphical Models and Bayesian Networks, 1998 (online).
\item Sam Roweis \& Zoubin Ghahramani, 1999. A Unifying Review of Linear Gaussian Models, Neural Computation 11(2) (1999) pp.305-345
\item C. Huang and A. Darwiche, 1996. "Inference in Belief Networks: A procedural guide", Intl. J. Approximate Reasoning, 15(3):225-263.
\item M. I. Jordan, Z. Ghahramani, T. S. Jaakkola, and L. K. Saul, 1997. "An introduction to variational methods for graphical models."
\item D. Heckerman, 1996. "A tutorial on learning with Bayesian networks", Microsoft Research tech. report, MSR-TR-95-06.
\end{itemize}
}

\section{Software}

\begin{frame}{Software for Graphical Models}
\begin{itemize}
\item BUGS and WinBUGS: inference via Gibbs sampling, not very scalable
\item HUGIN: widely used, commercial, focus on exact inference
\item \noteG{Kevin Murphy’s Bayes Net Toolbox}: Matlab, widely used
\item Microsoft’s Infer.NET: advanced scalable libraries implementing factor graph
propagation, EP, and variational message passing.
\item Jeff Bilmes’ GMTK: very good at HMMs and related time series models
\end{itemize}
\end{frame}

\frame{
\frametitle{A personal library}

\begin{itemize}
\item My personal website \url{https://github.com/olmosUC3M/Inference-and-Learning-in-discrete-Bayesian-Networks.git}
\item Not really scalable. The focus is on teaching through practice over small example using Python's notebooks.
\item Easy to interpret and extend.
\item Open Source.
\end{itemize}

}

\end{document}

%%% Local Variables:
%%% mode: latex
%%% TeX-master: t
%%% End:

Slides/Belief Propagation and Inference/BP and Inference.tex


\documentclass[conc-doc]{subfiles}

\begin{document}

	\chapter[Functions]{Functions}

Functions are a major part of procedural programming. They allows us to split up our programs into subroutines of logic designed to perform specific tasks. They are an incredibly useful abstraction which is used at all levels of the computational process of transforming a human readable description of how to perform a task, right down to the level machine code that our computer CPUs can understand.

Broadly speaking, a function takes a set of inputs variables and returns an output (or outputs if one takes advantage of Concurnas' ability for functions to return tuples) having executed code specified in a block of code associated with the function. The function has a name in order to make it possible for other functions to call it. The input variables have their specified types as does the return value. The input variables and return type constitute the signature of the function and along with the name (and package path) must be unique.

Here is a function, the \lstinline{def} keyword on its own is used to indicate that we are creating a function, followed by the name of the function, and any comma separated input parameters surrounded by a pair of parentheses \lstinline{( )} and a (optional) return type:

\begin{lstlisting}
def addTogether(a int, b int) int {
	return a + b
}
\end{lstlisting}

The /return/ keyword is used within a function in order to cease further execution and literally return the value on the right hand side of it from the function (or the innermost nested function if they are nested).

Now, the above is a perfectly acceptable way to define a function and although it is very verbose, is often the preferred method when writing complex code, or code for which the intended audience may require the extra verbosity in order to aid in their understanding of what is happening.

But there are a few refinements to the above which can make writing functions in Concurnas a quicker, more enjoyable less verbose experience with very little compromise to clarity.

Firstly, the type of the return value is usually inferable by Concurnas, in the above case it's \lstinline{int} so we can omit this from the definition and leave it implicit:

\begin{lstlisting}
def addTogether(a int, b int) {
	return a + b
}
\end{lstlisting}

Next we know that blocks are able to return values, so we don't need the \lstinline{return} keyword at all:

\begin{lstlisting}
def addTogether(a int, b int) {
	a + b
}
\end{lstlisting}

Now let us use the compact one line form of the \lstinline{block}, via \lstinline{=>}:

\begin{lstlisting}
def addTogether(a int, b int) => a + b
\end{lstlisting}

The above is functionally identical to our first definition but far more compact. It's a matter of discretion in so far as the degree to which one wishes to compact one's functions definitions, sometimes a less compact, more verbose form is more appropriate.

\section{Functions vs Methods}
In Concurnas, a distinction is drawn between the concept of functions and methods.

Simply put, functions are defined at root source code level, methods are defined within classes and have access to the internal state of instance objects of their host class (and any parent nestor classes if relevant), via the \lstinline{this} and \lstinline{super} keywords. Methods are covered in more detail here See Classes and Objects section. For now lets look at a simple example highlighting the distinction:

\begin{lstlisting}
def iAmAFunction() => "hi I'm a function"

class MyClass(id int){
	def iAmAMethod() => "hi I'm a method, my class holds the number: " + this.id
}
\end{lstlisting}

\section{Calling functions and methods}
Ordinarily, we require three things when calling a function, 1). the name of the function, 2). input arguments to qualify it's input parameters and 3). an understanding of the return type.

We can call our \lstinline{addTogether} function defined previously as follows:
\begin{lstlisting}
result int = addTogether(1, 1)
\end{lstlisting}

Also, we may use named arguments in order to call our function. This can often make method calls easier to read, especially where there are lots of arguments involved, some with default values some not etc. Named arguments do not have to be specified in the order in which they are defined in the function:

\begin{lstlisting}
result = addTogether(a=1, b=1)
result = addTogether(b=1, a=1)
\end{lstlisting}

The above two calls to \lstinline{addTogether} are functionally identical.

When it comes to calling (or invoking) methods, we need an additional component; an object to call the method on. To indicate that we are calling a function on a method, we need to use a dot \lstinline{.}, for example:

\begin{lstlisting}
class MyClass(state int){
	def myMethod(an input) => state += an; state
}

obj = new MyClass(10)
result = obj.myMethod(2)

//result == 12
\end{lstlisting}

If instead of whatever is returned from the method (if anything) we wish to return a reference to the object upon which we called the method, we can use the double dot notation: \lstinline{..}:

\begin{lstlisting}
obj = new MyClass(10)
result = obj..myMethod(2)..myMethod(10)

//result == 22
\end{lstlisting}

The double dot notation \lstinline{..} is particularly useful when we need to chain together multiple calls on the same object and do not wish to do perform any sort of operation on the returned values from the intermediate method calls.

We can use named arguments when calling methods:

\begin{lstlisting}
obj = new MyClass(10)
result = obj.myMethod(input = 2)

//result == 12
\end{lstlisting}

\section{Input parameters}
Functions specify a comma separated list of input variables consisting of a name and type. Each input variable name must be unique. They may optionally be preceded by \lstinline{var} or \lstinline{val}:

\begin{lstlisting}
def addTwo(var a int, val b int) => a+b

\end{lstlisting}

\section{Default arguments}
Function input arguments may specify a default value to use in cases where the input argument is not specified by the caller. When this is done, the type of the variable does not have to be specified if you're happy for Concurnas to infer the input parameter type:

\begin{lstlisting}
def doMath(an int, b int = 100, c = 10) => (an + b) * c

\end{lstlisting}

Then, when we call a function with default arguments, we do need to specify the arguments for which a default value has been defined:

\begin{lstlisting}
res = doMath(5)

//res == 1050
\end{lstlisting}

\section{Varargs}
Function parameters may consume more than one input parameter if they are declared as a vararg. A varag input parameter is signified by postfixing \lstinline{...} to the type of the parameter - note that this converts the input parameter to be an array if it's a single value type, or an n+1 dimensional array if it's already an n dimensional array. For example:

\begin{lstlisting}
def stringAndSum(prefix String, items int...){
	summ = 0L
	for( i in items){
		summ += i
	}
	prefix + summ
}

\end{lstlisting}

We can call a function with vararg parameters we can pass as many inputs to the vararg component as we need, seperated via a commas as par normal function invocation arguments:
\begin{lstlisting}
result = stringAndSum("the sum is: ", 2, 3, 2, 1, 3, 2, 1, 3, 4, 2, 4)

//result == "ths sum is: 27"
\end{lstlisting}

The vararg may alternatively be passed as an array type (or n+1 dimensional array as eluded previously):
\begin{lstlisting}
result = stringAndSum("the sum is: ", [2 3 2 1 3 2 1 3 4 2 4])

//result == "ths sum is: 27"
\end{lstlisting}

It's perfectly acceptable to not pass any input to the vararg parameter, e.g:

\begin{lstlisting}
result = stringAndSum("the sum is: ")

//result == "ths sum is: 27"
\end{lstlisting}

An n dimensional array type can be used as a varrag:
\begin{lstlisting}
def stringAndSum(prefix String, items int[]){
	summ = 0L
	for( i in items){
		summ += i
	}
	prefix + summ
}

result = stringAndSum("the sum is: ", 2, 3, 2, 1, 3, 2, 1, 3, 4, 2, 4)

//result == "ths sum is: 27"
\end{lstlisting}

\section{Nested functions}
Nested functions are appropriate in two cases:

\begin{enumerate}
	\item It makes sense to break one's code down into a subroutine - for instance, in order to avoid what would otherwise be code duplication
	\item One wishes for that sub function to only be callable within the nestor function - i.e. the nestor function is the only caller.
\end{enumerate}

A nested function is simply a function defined within a function. The scope of that function is bound to the scope of the nestor function, it cannot directly be called by code outside of the nestor function. Example:

\begin{lstlisting}
def parentFunction(apply int){
	result = 0L
	def dosomething(){
		result + (result + apply) * apply
	}
	//we wish to perform the above four times but avoid the code duplication, we also don't require any other code outside of parentFunction to be able to call it.

	result = dosomething()
	result = dosomething()
	result = dosomething()
	result = dosomething()
}
\end{lstlisting}

When it comes to using variables which are defined in the nestor function within the nested function, they are implicitly passed to the function but the nested function itself is defined as if it were separate from the nestor. For this reason, and by virtue of the fact that Concurnas uses pass by value for function arguments when calling functions the following is true:

\begin{lstlisting}
def parentFun(){
	parentVar = 100

	def nestedFunc(){
		parentVar += 100
		parentVar
	}

	result = nestedFunc()
	assert result == 200
	assert parentVar ==100
}
\end{lstlisting}

We see above that although our \lstinline{nestedFunc} has access to a copy of the value of the nestor variable \lstinline{parentVar} (as it is implicitly passed into the function), changes made to that variable within the function do not apply to the one in scope of the \lstinline{parentFun}.

But note that if we pass in an object, a copy of the reference to that object is passed to the nested function, so the behaviour is as follows:

\begin{lstlisting}
class IntHolder(~an int)

def parentFun(){
	parentVar = IntHolder(100)

	def nestedFunc(){
		parentVar.an += 100
		parentVar.an
	}

	result = nestedFunc()
	assert result == 200
	assert parentVar.an == 200
}
\end{lstlisting}

As \lstinline{parentVar} holds a reference to an object, the reference is copied, not the object itself, therefore the nestor function \lstinline{parentFun} and nested function \lstinline{nestedFunc} versions of the object referenced by variable \lstinline{parentVar} are the same - they are shared.

\section{Recursion}
Recursion is the process by which a function, either directly or indirectly calls itself. Concurnas permits function recursion (except for within GPU functions and GPU kernels). The classic textbook example of this being factorial number calculation:

\begin{lstlisting}
def factorial(n int){
	match(n){
		1 or 2 => 1
		else => factorial(n-1)+factorial(n-2)
	}
}

res = factorial(5)

//res == 5
\end{lstlisting}

It turns out that the above, for any value of n greater than 2 performs a lot of unnecessary repetitive work in terms of calling factorial for values already previously calculated. There are far better ways of calculating factorial numbers (some of which don't use recursion at all). Here is a different recursion example more likely to be seen in the wild, a tree traversal:

\begin{lstlisting}
open class Node

class Branch(~children Node...) < Node
class Leaf(~value String) < Node

def create(){
	Branch(Branch(Leaf("a"), Leaf("z")), Leaf("c"))
}

def explore(node Node){
	match(node){
		Branch => String.join(", ", (explore(n) for n in node.children))
		Leaf => "Leaf: {node.value}"
	}
}

tree = create()
res = explore(tree)

//res == Leaf: a, Leaf: z, Leaf: c
\end{lstlisting}

One thing to bear in mind with recursion is the fact that as we recurse, with every direct or indirect self call, we deepen the call stack. This is not a big deal if we recurse to a small degree, but if we are recursing a lot\footnote{\textit{A lot} sounds vague but this is intentional because the stack size is platform specific, so really we cannot be more precise than this.}, then we will be eating up our call stack which may result in us running out of stack causing a \lstinline{java.lang.StackOverflowError} exception to be thrown. It is for this reason that some organizations restrict the use of, or even outright ban the use of recursion.

\end{document}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% UMB-CS110-2015S: Introduction to Computing
% Copyright 2015 Pejman Ghorbanzade <pejman@ghorbanzade.com>
% Creative Commons Attribution-ShareAlike 4.0 International License
% More info: https://github.com/ghorbanzade/UMB-CS110-2015S
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\def \topDirectory {.}
\def \texDirectory {\topDirectory/src/main/tex}

\documentclass[12pt,letterpaper,twoside]{article}
\usepackage{\texDirectory/template/style/directives}
\usepackage{\texDirectory/template/style/assignment}
\input{\texDirectory/template/config}

\begin{document}

\doc{title}{Solution to Quiz 1(a)}
\doc{date-pub}{Feb 24, 2015 at 01:00 PM}
\doc{date-due}{Feb 24, 2015 at 11:00 PM}
\doc{points}{4}

\prepare{header}

\section*{Question 1}

Meet, from left to right, Joe, William, Jack and Averell, villains of our childhood that go by the name of the Dalton brothers. These inseparable brothers have a special rule among themselves. They always stand in order of their height.

Write a program \texttt{Daltons.java} that takes names of the brothers as command-line arguments and prints \texttt{false} unless the order in which arguments are given follows \textit{The Dalton Rule}.

Example:\\
\texttt{\% java TheDaltons Joe William Jack Averell > true}\\
\texttt{\% java TheDaltons Averell Jack William Joe > true}\\
\texttt{\% java TheDaltons Averell William Joe Jack > false}
\begin{figure}[H]\centering
\includegraphics[width=10cm]{\texDirectory/template/images/daltons.png}
\caption{The Dalton Brothers}\label{fig1}
\end{figure}

\subsection*{Solution}

\lstset{language=Java}
\begin{lstlisting}
public class Daltons {
	public static void main (String[] args) {
		boolean result = false;
		// Check if brothers are from shortest to tallest
		if (args[0].equals("Joe") && args[1].equals("William") && args[2].equals("Jack") && args[3].equals("Averell")) {
			result = true;
		}
		// Check if brothers are from tallest to shortest
		else if (args[0].equals("Averell") && args[1].equals("Jack") && args[2].equals("William") && args[3].equals("Joe")) {
			result = true;
		}
		System.out.println(result);
	}
}
\end{lstlisting}

\section*{Question 2}

Matthew and John are playing backgammon and they hate rolling the two dice each turn, over and over again.

\begin{enumerate}
	\item Write a program \texttt{Dice1.java} that gives two random integer numbers from one to six each time it is executed.
	\item Upgrade your program to \texttt{Dice2.java} such that it takes an integer number as command-line argument and generates two random integer values in the range of one to given integer number.
\end{enumerate}

\subsection*{Solution}

\begin{lstlisting}
public class Dice1 {
	public static void main (String[] args) {
		// Generating two random numbers between 0 to 1
		double rand1 = Math.random();
		double rand2 = Math.random();
		// Convert range of random numbers and make them integers
		int randInt1 = (int) (6*rand1 + 1);
		int randInt2 = (int) (6*rand2 + 1);
		System.out.println(randInt1);
		System.out.println(randInt2);
	}
}
\end{lstlisting}
\begin{lstlisting}
public class Dice2 {
	public static void main (String[] args) {

		// Converting command-line argument to integer
		int maxNum = Integer.parseInt(args[0]);

		// Generating two random numbers between 0 to 1
		double rand1 = Math.random();
		double rand2 = Math.random();

		// Convert range of random numbers and make them integers
		int randInt1 = (int) (maxNum*rand1 + 1);
		int randInt2 = (int) (maxNum*rand2 + 1);
		System.out.println("First random number between 1 and " + maxNum + ": " + randInt1);
		System.out.println("Second random number between 1 and " + maxNum + ": " + randInt2);
	}
}
\end{lstlisting}

\end{document}


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

% \section*{Tue Nov 12 2019}

Last time we estimated the radiation pressure due to one line.

If we know \(\dot{M} \) and the luminosity \(L\), then we can calculate the effective number of  lines: \(N _{\text{eff}} = \dot{M} c^2 / L\).

\begin{bluebox}
There will need to be more than these: they cannot \emph{all} be at the peak of the Planckian.
\end{bluebox}

For a hot luminous star with \(L \sim \num{e6} L_{\odot}\) the mass loss rate for a single line is \(L/c^2 \approx \num{7e-8} M_{\odot} / \SI{}{yr}\).
The observed mass loss rate is a hundred times higher, so we can say that \(N  _{\text{eff}} \sim \num{e2}\).

If \emph{all} of the star's light were to be absorbed by lines, then the momentum variation of the wind, \(\dot{M} v_{ \infty }\), will equal the total force applied by the star's emission: \(L/c\).

% \todo[inline]{Lamers calls this a balance of momenta but dimensionally they are forces!}
% This gives a bound on the mass loss rate:
% %
% \begin{align}
% \dot{M} _{\text{max}} = \frac{L}{v_{ \infty } c}
% \,,
% \end{align}
% %
% which is also called the \emph{single scattering limit}: it assumes that any photon is only scattered once. This is not a bad approximation: after the first scattering the photon's directions are much less collimated outwards, so the later scatterings are less effective.
% Later scatterings can actually contribute, and give rise to an enhanced mass loss rate.
% The enhancement factor can be as much as 6 for Wolf-Rayet stars!

So, we define the \emph{efficiency parameter}:
%
\begin{align}
  \eta = \frac{\dot{M} v_{\infty}}{L / c} = \frac{\dot{M}}{\dot{M} _{\text{max}}}
\,,
\end{align}
%
which represents the ratio between the real wind's mass loss rate and the theoretical maximum.

We can also look at the efficiency in the transmission of energy: we look at the variation of a certain type of energy, and compare it to the star's luminosity.
%
\begin{subequations}
\begin{align}
  \eta _{\text{pot}} &= \frac{\dot{E}_{\text{pot}}}{L}  = \frac{\dot{M} G M_{*}}{R_{*}L}  \\
  \eta _{\text{kin}} &= \frac{\dot{E}_k}{L} = \frac{\dot{M} v_{\infty}^2}{2L}  \\
  \eta _{\text{th}} &= \frac{5 \dot{M} R T_w}{2 \mu L}
  \,,
\end{align}
\end{subequations}
%
while the \(\eta = \eta _{\text{mom}} = \dot{M} v_{ \infty }c / L\) we defined before was the efficiency in the transmission of \emph{momentum}.
The main point is: \emph{momentum transfer is efficient, energy transfer is not}.
To see this, let us consider a star which, like the example from before, operated with \(\eta_{\text{mom}} = 1\). This is realistic, and matches observations.
Then, let us compute \(\eta _{\text{kin}}\): it is
%
\begin{align}
\eta _{\text{kin}} = \frac{\dot{M} v_{ \infty }^2}{2L}
= \frac{v_{ \infty }^2}{2L} \frac{L}{v_{ \infty }c}=
\frac{v_{ \infty }}{2c}
\,,
\end{align}
%
which, as we know, is very small: the wind's terminal speed is very much subluminal.

We'd expect \(\eta _{\text{mom}} \leq 1\), but actually sometimes the momentum efficiency can be larger: for WR stars we have \(\eta _{\text{mom}} \approx 59\).

If across all the spectrum of the star we have completely optically thick absorption, then the momentum of the wind is equal to the momentum of radiation:
%
\begin{align} \label{eq:completely-optically-thick}
  \dot{M} _{\text{max}} v_{\infty} = \frac{L}{c}
  \implies \dot{M} _{\text{max}} = \frac{L}{c v_{\infty}}
\,,
\end{align}
%
and typically \(v_{\infty}\) is of the order of 2, 3 times the escape velocity at the photosphere: \(v_{\infty} \approx 3 \sqrt{2 GM / R}\).
For the luminosity we consider \(L = \num{e5} L_{\odot}\).

Then, the maximum mass loss rate estimated by \eqref{eq:completely-optically-thick} is similar to the observed one. The ratio \(\eta _{\text{momentum}} = \dot{M} / \dot{M} _{\text{max}}\) is typically \(0.5 \divisionsymbol 1 \), but for some stars it can be of the order \num{e1} to \num{e2}.

This is called the \emph{single scattering upper limit}: we assume that scattering is isotropic, therefore we'd expect that after the first scattering the photon does not contribute anymore.
This is not actually the case: \emph{multiple scattering} can contribute, enhancing the maximum mass loss rate by the optical depth of the wind, \(\tau_{w}\), which is equal to
%
\begin{align}
\tau_{w} = \int _{r_c}^{\infty} \kappa \rho \dd{r}
\,,
\end{align}
%
so \(\dot{M} _{\text{max, multiple scattering}} =\tau_{w} \dot{M} _{\text{max, single scattering}}\).

This typically gives us enhancement factors of the order \(2\) to \(6\).
The quantity \(\tau _w\) is adimensional, since the units of \(\kappa \) are \SI{}{cm^2/g}.

Even though we have this corrective factor, the efficiency is always expressed with respect to the single scattering cross section.
Multiple scattering theory accounts for all of the increased mass loss rate, even up to \(\tau \sim \num{e2}\).

\todo[inline]{How does it account for the approximate isotropy of the radiation after the first scattering?}

\subsubsection{Radiation pressure due to one line}

Now, we derive the expression for the radiative acceleration privided by one line in a moving atmosphere.

We have a unit volume, of \SI{1}{cm^3}, it has a velocity gradient inside it from \(v\) to \(v + \Delta v\), and it will be heated by a monochromatic flux given by \(F_{\nu } = I_{\nu } / (4 \pi r^2)\).

What is the acceleration \(g _{\text{line}}\)?
First we need to know the absorption properties of the medium.
The absorption coefficient per cubic centimeter of gas is
%
\begin{align} \label{eq:opacity-expression}
  \kappa_{\nu } = \frac{\pi e^2}{m_e c 4 \pi \epsilon_0} f n_i \phi (\nu )
\,,
\end{align}
%
where \(\pi e^2/ (4 \pi \epsilon_0 m_e c) \approx \SI{2.654e-2}{cm^2/s}\) is the frequency integrated cross section\footnote{We introduce the factor of \(1/4 \pi \epsilon_0 \) because like civilized people we prefer the International System of units. However, from here on out we will use Gaussian units (set \(4 \pi \epsilon_0 =1\)) since I do not want to change all the formulas.} of the classical oscillator (for the electron):
%
\begin{align}
  \frac{\pi e^2}{m_e c} = \sigma = \int_0^{\infty} \sigma (\nu ) \dd{\nu }
\,;
\end{align}
%
\(f\) is the oscillator strength, which depends on the line (it is a correction needed to account for quantum effects);
\(n_i\) is the number density of atoms which can absorb the line, and \(\phi (\nu )\) is the Gaussian profile of the absorption coefficient, centered at the rest frequency \(\nu_0 \), and normalized so that \(\int \phi (\nu ) \dd{\nu } = 1\): therefore the units of \(\phi\) are \SI{}{1/Hz}.

\todo[inline]{This \(\kappa_{\nu } \) is not the same as the one in the expression \(\tau = \int \kappa \rho \dd{r}\): this one actually is \(\kappa \rho \) already, since it has the units \(\SI{}{1/m}\).}

The typical profile function is a \emph{Doppler profile}: its width is of an order based on the thermal velocity of the atoms (divided by \(c\)), which can be approximated as much less than the wind velocity (as long as there is no turbulence): so, we apply the \emph{Sobolev approximation}, and estimate \(\phi (\nu ) \sim \delta (\nu - \nu_0 )\).

So we need to consider lines which do not overlap.

Newton's second law, expressed as a function of force, momentum and energy \emph{per unit volume}, reads:
%
\begin{align}
  F _{\text{rad}} = \dv{P _{\text{rad}}}{t}
  = \frac{1}{c} \dv{E _{\text{rad}}}{t}
\,,
\end{align}
%
where \(\dv*{E _{\text{rad}}}{t}\) is the radiative energy absorbed per unit time and volume by the line.

Then, the acceleration due to the line is:
%
\begin{align} \label{eq:line-acceleration-general}
  g _{\text{line}} = \frac{F _{\text{rad}}}{\rho }
  = \frac{1}{c \rho } \dv{E _{\text{rad}}}{t}
\,.
\end{align}

We still need to calculate the radiative energy absorbed: for a single optically thick line it is given by \(\dv*{E _{\text{rad}}}{t} = F_{\nu } \kappa _{\text{line}}\), so in the end the line acceleration is
%
\begin{align}
g _{\text{line}} = \frac{\kappa _{\text{line}} F_{\nu }}{c \rho }
\,.
\end{align}
%
\todo[inline]{This \(\kappa _{\text{line}}\) has the dimensions of \(\SI{}{m^2 /s}\): it is not the same as a regular opacity, which is a cross-section per unit mass.}

\subsection{Optically thick and optically thin case}

A more general expression is:
%
\begin{align}
  g _{\text{rad}} = \frac{F_{\nu_0} \nu_0 }{c} \qty(1 - \exp(- \tau_{\nu_0 }) ) \dv{v}{r} \frac{1}{c \rho }
\,;
\end{align}
%
here \(F_{\nu_0}\) is the monochromatic flux from the star emitted at the line rest frequency \(\nu_0 \), the quantity
%
\begin{align}
  \frac{\nu_0}{c} \dv{v}{r}
\,
\end{align}
%
is the width of the frequency band that can be absorbed, while \(1 - \exp(-\tau ) \) is the probability that the absorption occurs in our cubic centimeter: there \(\tau \) is the optical depth (integrated up to infinity).

The product of these three terms gives an energy absorption rate \(\dv*{E _{\text{rad}}}{t}\), if we multiply by \(1/c\) we get absorbed momentum, if we multiply by \(1/ \rho \) we get acceleration.

\paragraph{Optically thin line}

Let us start from optically thin lines: they absorb only part of the radiative flux.

Then \(\tau_{\nu_0 } \) is small, so we get \(\exp(-\tau_{\nu_0 }) \sim 1- \tau_{\nu_0 } \), therefore \(1- \exp(-\tau_{\nu_0 }) \approx \tau_{\nu_0 } \).

% \todo[inline]{So what? there seems to be a factor \(\rho \) missing\dots}

So, we can substitute \eqref{eq:opacity-expression} into \eqref{eq:line-acceleration-general}, and we get:
%
\begin{align}
g_{\text{line}} = \frac{F_{\nu }}{c} \frac{n_i}{\rho } \qty(f \frac{\pi e^2}{m_e c}) \sim \frac{L_{\nu }}{r^2} \frac{n_i}{\rho }
\,,
\end{align}
%
where \(L_{\nu }\) is the monochromatic luminosity of the star: we have \(F_{\nu } \sim L_{\nu }/ r^2\), the factor of \(4 \pi \) does not make much of a difference.
We can approximate \(n_i / \rho \) as a constant with respect to the radius: it depends on the ionization ratio of the gas, which will not change much. Therefore, we have \(g _{\text{line}} \propto L_{\nu } / r^2\).

\end{document}


\section{3D computer vision overview}
The laser-camera triangulation system is not the only way to perform 3D world reconstruction. The most commonly used technologies are:
\begin{itemize}
  \item \textsc{Stereo Vision} - The typical stereo vision system is a binocular system, composed by two cameras displaced horizontally, viewing the same scene at two slightly different angles. Thanks to the epipolar geometry it is possible to determine where a specific 3D world point is projected into the 2D planes of the two cameras. After determining these relations, the relative depth information can be obtained in the form of a disparity map, which encodes the differences in horizontal coordinates of corresponding image points. The values in this disparity map are inversely proportional to the scene depth at the corresponding pixel location.

  \item \textsc{Structured light} - Similarly to \acs{SOL} technology, structured light sensors are made by a camera and by a source of light (DLP-projector) that project know patterns, alternating bright and dark. Patterns are deformed because of the shape of the target as with \acs{SOL}, and triangulation is used for the 3D reconstruction. The main benefit of using a DLP-projector rather than a fixed light line is that the projection project the pattern over the whole scene, and mechanical translation or motion required by SOL is not required.

  \item \textsc{Time Of Flight (\acs{TOF})} - This technique is the youngest of the ones proposed. \acs{TOF} sensors estimate distances by measuring the time needed to a signal (light, electromagnetic, acoustic, ...) to reach an obstacle and come back to the sensor. One of the benefits of using this technique is the independence of the calculated distances for each pixel, allowing very high accuracy, but this type of sensors are very delicate and require a lot of handling. \acs{LIDAR} (Light Detection And Ranging) is the first example of \acs{TOF} technology.

\end{itemize}
Typically these names are also used to refer to sensors that exploit the specific technology.


\chapter{Defining Clades by their Descendants}
\label{sct_def_clades}

When you need to specify a clade using the \nutils{}, you either give the label
of the clade's root, or the labels of (some of) its descendants. Since inner
nodes rarely have labels (or worse, have unusable labels like bootstrap
support values), you will often need to specify clades by their descendants.
Consider the following tree:

\begin{center}
\includegraphics{clade_2_svg.pdf}
\end{center}

\noindent{}Suppose we want to specify the Hominoidea clade - the apes. It is
the clade that contains \texttt{Homo}, \texttt{Pan} (chimps), \texttt{Gorilla},
\texttt{Pongo} (orangutan), and \texttt{Hylobates} (gibbons). The clade is not
labeled in this tree, but this list of labels defines it without ambiguity. In
fact, we can define it unambiguously using just \texttt{Hylobates} and
\texttt{Homo} - or \texttt{Hylobates} and any other label. The point is that
\emph{you never need more than two labels to unambiguously define a clade}.

You cannot choose any two nodes, however: the condition is that the last
common ancestor of the two nodes be the root of the desired clade. For
instance, if you used \texttt{Pongo} instead of \texttt{Hylobates}, you would
define the Hominidae clade, leaving out the gibbons.

\section{Why not just use node numbers?}

Some applications attribute numbers to all inner nodes and allow users to
specify clades by referring to this number. Such a scheme is not workable when
one has many input trees, however, because there is no guarantee that the same
clade (assuming it is present) will have the same number in different trees.


\subsection{Small DB 2, the dynamic array version in C} % (fold)
\label{sub:small_db_2_the_dynamic_array_version}

\sref{sec:using_dynamic_memory_allocation}, \nameref{sec:using_dynamic_memory_allocation}, introduced a version of the Small DB program with a dynamic array structure, as opposed to the fixed array structure used to manage the rows in \cref{cha:more_data_types}. The C code for the altered functions and procedures is shown in \lref{clst:dynamic-array-db}, the original version can be found in \lref{lst:c-small-db}.

\straightcode{\ccode{clst:dynamic-array-db}{C code for the dynamic array version of Small DB, see \lref{lst:c-small-db} for the original version of this program}{code/c/dynamic-memory/array-db-for-chap.c}}

\mynote{
\begin{itemize}
  \item This version of the Small DB program includes the ability to add, delete, and print rows from the data store.
  \item The data store includes a dynamic array that is managed using \nameref{ssub:realloc}.
  \item See \sref{sec:using_dynamic_memory_allocation} for a discussion of how this works.
\end{itemize}
}


\section{Introduction}
Housing prices are an important reflection of the economy, and pricing a rental property on Airbnb, therefore, can be a challenging task for the owner as it determines the number of customers for the place. On the other hand, customers have to evaluate an offered price with minimal knowledge of an optimal value for the property.
\footnote{GitHub repository for the project: \url{https://github.com/edofazza/AirBnBPriceEstimator}}

\subsection{Goals}
The aim of this paper is to explain the choices and the strategies we adopted on the project and development of \textbf{AirBnb Price Estimator}, whose aim is to help owners to decide the most correct price for their \textit{BnB}.
In order to accomplish it, we started from web-scraped data, we performed all the preprocessing needed for having a suitable dataset and then we built several classifiers, using different strategies, in order to determine the one that predicts best the class attribute. All these classifiers have been tested using more than one method and the analysis of the results guided us in the choice of the best classifier.
Since the class attribute is numeric, we had two possible choices:

\begin{enumerate}
	\item Discretize the attribute, choosing the most appropriate algorithm
	\item Keep it numeric, using regression algorithms for the classification purposes
\end{enumerate}
The first approach is surely easier, but it would not be as helpful as the second one for our application purposes: suggesting a precise value to an owner will give him/her a more accurate advice rather than a range.

The regression model that generalizes best the class feature has then been chosen as the “heart” of AirBnB Price Estimator: the application asks users to input the required fields that correspond to the attributes needed by the classificatory. On these fields bases, it simply outputs to the user the suggested price for night.

\subsection{Initial Dataset}
The fee of a real estate is strictly related to the city where it is located, thus would force us to recompute for every different city each step we make over and over, wasting time. Thus we decide to consider only one location (i.e, city), big enough to have a huge number of records. We chose \textit{New York City}.
The dataset, related to all the \textbf{BnB} situated in \textit{NYC}, is taken from \url{http://insideairbnb.com/get-the-data.html} \footnote{In the case of the dataset form the website inside the \textit{listing.csv} file, related to NYC, is updated, we stored the dataset used on Google Drive. It can be downloaded at: \url{https://drive.google.com/file/d/1KQ2yB6eJOrbSZoyL5fxWJjq72i4ONyQn/view?usp=sharing}}. The scraping has been performed the 10th November 2020 (the scraped data has been made available by third parties).

The \textit{initial dataset} is composed by 35821 instances and 74 columns. In order not to confuse the reader with useless information, the attribute list is not here reported, however on the following chapter regarding preprocessing we justify in detail the actions performed on the data. For now, the most important things to know is that:

\begin{enumerate}
	\item The dataset is composed by various mixed features regarding the estate, the host and he geographical position
	\item The source file has been published without respecting exactly the \textit{csv} format, thus some frameworks and \textit{csv} file handlers are not able to parse it
	\item The initial data is very dirty: there are missing values, redundant attributes, lists of strings embedded in a single column, pointless features and so on. For all of these problems, a suitable solution has been provided and it is fully reported on the next chapter.
\end{enumerate}

\medskip
% //


%                                                                 aa.dem
% AA vers. 8.2, LaTeX class for Astronomy & Astrophysics
% demonstration file
%                                                       (c) EDP Sciences
%-----------------------------------------------------------------------
%
%\documentclass[referee]{aa} % for a referee version
%\documentclass[onecolumn]{aa} % for a paper on 1 column
%\documentclass[longauth]{aa} % for the long lists of affiliations
%\documentclass[rnote]{aa} % for the research notes
%\documentclass[letter]{aa} % for the letters
%\documentclass[bibyear]{aa} % if the references are not structured
% according to the author-year natbib style

%
\documentclass{aa}

%
\usepackage{graphicx}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\usepackage{txfonts}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\usepackage{hyperref}
% To add links in your PDF file, use the package "hyperref"
% with options according to your LaTeX or PDFLaTeX drivers.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\usepackage{natbib}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\usepackage[pyfuture=none]{pythontex}

\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}

\newcommand{\pytex}{Python\TeX}

%
\begin{document}

   \title{Python\TeX}

   \subtitle{}

   \author{João Faria
          \inst{1}
          }

   \institute{Programmer's Club, Feb 26 2015}

   \date{Received ...; accepted ....}

% \abstract{}{}{}{}{}
% 5 {} token are mandatory

  \abstract
  % context heading (optional)
  % {} leave it empty if necessary
   {To investigate the physical nature of the `nuc\-leated instability' of
   proto giant planets, the stability of layers
   in static, radiative gas spheres is analysed on the basis of Baker's
   standard one-zone model.}
  % aims heading (mandatory)
   {It is shown that stability
   depends only upon the equations of state, the opacities and the local
   thermodynamic state in the layer. Stability and instability can
   therefore be expressed in the form of stability equations of state
   which are universal for a given composition.}
  % methods heading (mandatory)
   {The stability equations of state are
   calculated for solar composition and are displayed in the domain
   $-14 \leq \lg \rho / \mathrm{[g\, cm^{-3}]} \leq 0 $,
   $ 8.8 \leq \lg e / \mathrm{[erg\, g^{-1}]} \leq 17.7$. These displays
   may be
   used to determine the one-zone stability of layers in stellar
   or planetary structure models by directly reading off the value of
   the stability equations for the thermodynamic state of these layers,
   specified
   by state quantities as density $\rho$, temperature $T$ or
   specific internal energy $e$.
   Regions of instability in the $(\rho,e)$-plane are described
   and related to the underlying microphysical processes.}
  % results heading (mandatory)
   {Vibrational instability is found to be a common phenomenon
   at temperatures lower than the second He ionisation
   zone. The $\kappa$-mechanism is widespread under `cool'
   conditions.}
  % conclusions heading (optional), leave it empty if necessary
   {}

   \keywords{giant planet formation --
                $\kappa$-mechanism --
                stability of gas spheres
               }

   \maketitle
%
%________________________________________________________________

\section{Introduction}

  This paper is about \pytex, which allows to enter Python code within a \LaTeX document, execute the code and access its output in the document.

  Let us try a few simple commands:

  \begin{itemize}
    \item \pygment{latex}{\py} returns a string representation of its argument. \\ For example, \pygment{latex}{\py{2 + 4**2}} produces \py{2 + 4**2}, and \pygment{latex}{\py{'ABC'.lower()}} produces \py{'ABC'.lower()}.
    \\

    \item \pygment{latex}{\pyc} executes code. \\
    For example, \pygment{latex}{\pyc{var = 2}} \pyc{var = 2} creates a variable, and then its value can be accessed later via \pygment{latex}{\py{var}}: \py{var}.\\
    Another example: \pygment{latex}{\pyc{from numpy import pi}} \pyc{from numpy import pi} and later in the document \pygment{latex}{\py{pi}}: \py{pi}
    \\

    \item \pygment{latex}{\pyb} executes and typesets code.\\
    For example, \pygment{latex}{\pyb{var = 2}} typesets \pyb{var = 2} in addition to creating the variable.
  \end{itemize}

  There are also a handful of environments

  \begin{itemize}
    \item \pygment{latex}{\begin{pycode}} code that is executed but not typeset
    \item \pygment{latex}{\begin{pyverbatim}} code that is typeset but not executed
    \item \pygment{latex}{\begin{pyblock}} code that is both executed and typeset
  \end{itemize}

  All commands and environments can be prepended with \pygment{latex}{\pylab} to import matplotlib's \textt{pylab} module, or with \pygment{latex}{\sympy} to import \textt{sympy}.

%__________________________________________________________________

\section{Why is this useful?}

  \subsection{To make tables automatically}

    Table values can be filled in from Python and the \pygment{latex}{\pycode} environment used to include them in the document.

\begin{pycode}
print r'\begin{table}[h]'
print r'\begin{tabular}{l|lll}'
a, b, c = 12, 3, 6
print r'name & a & b & c \\'
print 'value & {} & {} & {}'.format(a,b,c)
print r'\end{tabular}'
print r'\end{table}'
\end{pycode}

  \subsection{To avoid copy/paste}

    Copying and pasting values into the \LaTeX\ document can be tedious and error-prone. If the variables are set in Python, we can access them by their name.

\begin{pygments}{text}
\begin{pycode}
import numpy as np
stars = np.loadtxt('sample.rdb', dtype='S')
nstars = d.size
nstars_HD = len([s for s in stars if s.startswith('HD')])
\end{pycode}
\end{pygments}

\begin{pycode}
import numpy as np
d = np.loadtxt('sample.rdb', dtype='S')
nstars = d.size
nstars_HD = len([star for star in d if star.startswith('HD')])
\end{pycode}

    There are \pygment{latex}{\py{nstars}}:\py{nstars} stars in our sample, \pygment{latex}{\py{nstars_HD}}:\py{nstars_HD} of which start with `HD'.

  \subsection{For automatic calculus}

    If we use SymPy we can have Python perform algebraic manipulations and then properly typeset the results.

\begin{sympyblock}
var('x, y, z')
z = x + y
\end{sympyblock}

To typeset the variable $z$ in an equation, use \pygment{latex}{\sympy{z}}.
We set $z$ to $\sympy{z}$.

Calculus becomes easy(ier):

\begin{sympyblock}
f = x**3 + cos(x)**5
g = Integral(f, x)
\end{sympyblock}

The LHS of Eq. \ref{eq:sympy} was typeset with \pygment{latex}{\sympy{g}}. The integral is then evaluated and typeset with \pygment{latex}{\sympy{g.doit()}}

\begin{equation} \label{eq:sympy}
  \sympy{g}=\sympy{g.doit()}
\end{equation}

It's easy to use arbitrary symbols in equations.

\begin{sympyblock}
phi = Symbol(r'\phi')
h = Integral(exp(-phi**2), (phi, 0, oo))
\end{sympyblock}

\begin{equation}
  \sympy{h}=\sympy{h.doit()}
\end{equation}

  \subsection{To make reproducible papers}

    If the final version of your paper is compiled with \pytex, you know for sure that the numerical results included in it are the exact ones coming out of your code.

    Therefore, if you happen to publish your code, and someone tries to reproduce your paper, they will get the exact same answer.

  \subsection{To include figures}

    It's useful to have the code that created a figure, together with that figure.

\begin{pylabblock}
rc('text', usetex=True)
rc('font', family='serif', size=10)
rc('legend', fontsize=10.0)
x = linspace(0, 10)
figure(figsize=(4, 2.5))
plot(x, sin(x), label='$\sin(x)$')
xlabel(r'$x\mathrm{-axis}$')
ylabel(r'$y\mathrm{-axis}$')
legend(loc=4)
savefig('myplot.pdf', bbox_inches='tight')
\end{pylabblock}

    Now we just have to load the \texttt{myplot.pdf} file and show it in Fig. \ref{fig:sine}.

    \begin{figure}
    \centering
    \includegraphics[width=\hsize]{myplot.pdf}
      \caption{A sine function.}
      \label{fig:sine}
    \end{figure}

    We could also create the figure in a separate file \texttt{makefigs.py} and assign it to a variable \texttt{fig1} and then use

\begin{pygments}{python}
\begin{pylabcode}
execfile('makefigs.py')
fig1.savefig('fig1.pdf', bbox_inches='tight')
\end{pylabcode}
\end{pygments}

\begin{pylabcode}
pytex.add_dependencies('makefigs.py')
execfile('makefigs.py')
fig1.savefig('fig1.pdf', bbox_inches='tight')
pytex.add_created(['fig1.pdf'])
\end{pylabcode}

    \begin{figure}
    \centering
    \includegraphics[width=\hsize]{fig1.pdf}
      \caption{A cosine function.}
      \label{fig:cosine}
    \end{figure}

\section{dePython\TeX}

  Journals don't really like \LaTeX\ files with weird commands in them. So there is a {\tt depythontex} command that can convert a Python\TeX\ document into a plain \LaTeX\ document. This does not change anything that was included from Python.

%-------------------------------------------------------------------

\begin{thebibliography}{}

\bibitem{poore2013}
  Geoffrey M. Poore,
  \emph{Reproducible Documents with PythonTeX}.
  Proceedings of the 12th Python in Science Conference, 78-84, 2013,
  \href{http://conference.scipy.org/proceedings/scipy2013/poore.html}{http://conference.scipy.org/proceedings/scipy2013/poore.html}

\end{thebibliography}

\end{document}


\documentclass[14pt]{beamer}
\usepackage{multimedia}

\usetheme[width=1.4cm]{PaloAlto}
\usecolortheme{default}
\useoutertheme{shadow}

\usepackage[utf8]{inputenc}
\usepackage{booktabs,tabu}
\usepackage{adjustbox}
\usepackage{graphicx}
\usepackage{caption}
\graphicspath{{figs/}}
\DeclareGraphicsRule{.tif}{png}{.png}{`convert #1 `dirname #1`/`basename #1 .tif`.png}

%%%%%%%%%%%%%%%%%%%%
%%% BEGIN PYTHON %%%
%%%%%%%%%%%%%%%%%%%%

\usepackage{color}
\long\def\ans#1{{\color{blue}{\em #1}}}
\long\def\ansnem#1{{\color{blue}#1}}
\long\def\boldred#1{{\color{red}{\bf #1}}}

\usepackage{listings}
\usepackage{textcomp}
\renewcommand{\lstlistlistingname}{Code Listings}
\renewcommand{\lstlistingname}{Code Listing}

%%% Specific for python listings
\definecolor{gray}{gray}{0.5}
\definecolor{green}{rgb}{0,0.5,0}

\lstnewenvironment{python}[1][]{
\lstset{
language=python,
basicstyle=\tiny,
stringstyle=\color{red},
showstringspaces=false,
alsoletter={1234567890},
otherkeywords={\ , \}, \{},
keywordstyle=\color{blue},
emph={access,and,break,class,continue,def,del,elif ,else,%
except,exec,finally,for,from,global,if,import,in,i s,%
lambda,not,or,pass,print,raise,return,try,while},
emphstyle=\color{black}\bfseries,
emph={[2]True, False, None, self},
emphstyle=[2]\color{green},
emph={[3]from, import, as},
emphstyle=[3]\color{blue},
upquote=true,
morecomment=[s]{"""}{"""},
commentstyle=\color{gray}\slshape,
emph={[4]1, 2, 3, 4, 5, 6, 7, 8, 9, 0},
emphstyle=[4]\color{blue},
literate=*{:}{{\textcolor{blue}:}}{1}%
{=}{{\textcolor{blue}=}}{1}%
{-}{{\textcolor{blue}-}}{1}%
{+}{{\textcolor{blue}+}}{1}%
{*}{{\textcolor{blue}*}}{1}%
{!}{{\textcolor{blue}!}}{1}%
{(}{{\textcolor{blue}(}}{1}%
{)}{{\textcolor{blue})}}{1}%
{[}{{\textcolor{blue}[}}{1}%
{]}{{\textcolor{blue}]}}{1}%
{<}{{\textcolor{blue}<}}{1}%
{>}{{\textcolor{blue}>}}{1},%
%framexleftmargin=1mm, framextopmargin=1mm, frame=shadowbox, rulesepcolor=\color{blue},#1
framexleftmargin=1mm, framextopmargin=1mm, frame=single,#1
}}{}

%%%%%%%%%%%%%%%%%%
%%% END PYTHON %%%
%%%%%%%%%%%%%%%%%%

% remove navigation symbols
\setbeamertemplate{navigation symbols}{}
\setbeamerfont{page number in head/foot}{size=\fontsize{12}{12}}
\setbeamertemplate{footline}[frame number]

% make image sized to frame
\newcommand {\framedgraphic}[2] { % args = {frametitle}{image.ext}
    \begin{frame}{#1}
        \begin{center}
            \includegraphics[width=\textwidth,height=0.8\textheight,keepaspectratio]{#2}
        \end{center}
    \end{frame}
}

% This block will remove authornames and talk title from sidebar
\makeatletter
  \setbeamertemplate{sidebar \beamer@sidebarside}%{sidebar theme}
  {
    \beamer@tempdim=\beamer@sidebarwidth%
    \advance\beamer@tempdim by -6pt%
    \insertverticalnavigation{\beamer@sidebarwidth}%
    \vfill
    \ifx\beamer@sidebarside\beamer@lefttext%
    \else%
      \usebeamercolor{normal text}%
      \llap{\usebeamertemplate***{navigation symbols}\hskip0.1cm}%
      \vskip2pt%
    \fi%
}%
\makeatother

\begin{document}

\title{A TensorFlow Tutorial}
\subtitle{Email Classification with Logistic Regression}
\author{Josh Meyer \inst{1} \and Michael Capizzi \inst{2}}
\institute{ \inst{1} University of Arizona \and \inst{2} PitchVantage}
\date{}

\frame{\titlepage}

\frame{\frametitle{Table of contents}\tableofcontents}

\section{What's Going to Happen}

\frame{
Tonight we will...
\begin{itemize}
\item describe the basic TensorFlow structures
\item build a working example of text classification
\item point out places where \textit{other} TensorFlow "built-ins" apply {\footnotesize(optimizers, cost functions, etc)}
\item "hand-wave" liberally \\
{\footnotesize(when we don't want to get into it or don't know the answer)}
\end{itemize}
Tonight we will \textbf{not}...
\begin{itemize}
\item discuss details of NLP feature selection
\item discuss details of Machine Learning \\
{\footnotesize(linear algebra, backpropogation, etc.)}
\end{itemize}
}

\section{TensorFlow Structures}

\frame{\frametitle{}
  \centering
    \begingroup
    \fontsize{20pt}{20pt}\selectfont
    TensorFlow Structures
  \endgroup
  \begin{flushleft}
  tensor = \textit{n}-dimensional matrix
  \end{flushleft}
\includegraphics[width=\textwidth,height=0.9\textheight,keepaspectratio]{tensors.png}}

\begin{frame}[fragile]
\frametitle{TensorFlow Structures}
\begin{itemize}
\item{\textbf{constants}}: {\small \textit{never} changes its value(s)} \\
\begin{python}
c = tf.constant(2.0, name="constantC") #can be int, float, or tensor
\end{python}
\item{\textbf{placeholders}}: {\small shell into which tensors can be iteratively inserted} \\
\begin{python}
X = tf.placeholder(tf.float32, [None, 200], name="input")
\end{python}
\item{\textbf{variables}}: {\small value(s) can be updated}
\begin{python}
weights = tf.Variable(tf.random_normal([1, 200], name="weights"))
\end{python}
\item{\textbf{operations}}: {\small computations that will act on tensors}
\begin{python}
apply_weights_OP = tf.matmul(X, weights, name="apply_weights")
add_bias_OP = tf.add(apply_weights_OP, bias, name="add_bias")
activation_OP = tf.nn.sigmoid(add_bias_OP, name="activation")\end{python}
\end{itemize}
\end{frame}

\section{The Flow of TensorFlow}

\frame{\frametitle{}
  \centering
    \begingroup
    \fontsize{20pt}{20pt}\selectfont
    Let's get to the script!\\
  \endgroup
}

\begin{frame}[fragile]
  \frametitle{Preamble}
  \begin{python}
################
### PREAMBLE ###
################

from __future__ import division
import tensorflow as tf
import numpy as np
import tarfile
import os
import matplotlib.pyplot as plt
import time
  \end{python}
\end{frame}

\begin{frame}[fragile]
  \frametitle{Import the Email Data}
  \begin{python}
###################
### IMPORT DATA ###
###################

def csv_to_numpy_array(filePath, delimiter):
    return np.genfromtxt(filePath, delimiter=delimiter, dtype=None)

def import_data():
    if "data" not in os.listdir(os.getcwd()):
        # Untar directory of data if we haven't already
        tarObject = tarfile.open("data.tar.gz")
        tarObject.extractall()
        tarObject.close()
        print("Extracted tar to current directory")
    else:
        # we've already extracted the files
        pass

    print("loading training data")
    trainX = csv_to_numpy_array("data/trainX.csv", delimiter="\t")
    trainY = csv_to_numpy_array("data/trainY.csv", delimiter="\t")
    print("loading test data")
    testX = csv_to_numpy_array("data/testX.csv", delimiter="\t")
    testY = csv_to_numpy_array("data/testY.csv", delimiter="\t")
    return trainX,trainY,testX,testY

trainX,trainY,testX,testY = import_data()
  \end{python}
\end{frame}

\begin{frame}[fragile]
  \frametitle{Some Global Parameters}
  \begin{python}
#########################
### GLOBAL PARAMETERS ###
#########################

# DATA SET PARAMETERS
# Get our dimensions for our different variables and placeholders:
# numFeatures = the number of words extracted from each email
numFeatures = trainX.shape[1]
# numLabels = number of classes we are predicting (here just 2: Ham or Spam)
numLabels = trainY.shape[1]

# TRAINING SESSION PARAMETERS
# number of times we iterate through training data
# tensorboard shows that accuracy plateaus at ~25k epochs
numEpochs = 27000
# a smarter learning rate for gradientOptimizer
learningRate = tf.train.exponential_decay(learning_rate=0.0008,
                                          global_step= 1,
                                          decay_steps=trainX.shape[0],
                                          decay_rate= 0.95,
                                          staircase=True)
  \end{python}
\end{frame}

\frame{\frametitle{}
  \centering
    \begingroup
    \fontsize{20pt}{20pt}\selectfont
    The Computational Graph\\
  \endgroup
}

\framedgraphic{The Full Computational Graph}{full-graph.png}

\framedgraphic{Define Feature and Label Placeholders}{define-X-Y-matrices.png}

\begin{frame}[fragile]
  \frametitle{Define Feature and Label Placeholders}
  \begin{python}
####################
### PLACEHOLDERS ###
####################

# X = X-matrix / feature-matrix / data-matrix... It's a tensor to hold our
# email data. 'None' here means that we can hold any number of emails
X = tf.placeholder(tf.float32, [None, numFeatures])

# yGold = Y-matrix / label-matrix / labels... This will be our correct answers
# matrix. Every row has either [1,0] for SPAM or [0,1] for HAM. 'None' here
# means that we can hold any number of emails
yGold = tf.placeholder(tf.float32, [None, numLabels])
  \end{python}
\end{frame}

\framedgraphic{Initialize Weights \& Bias Terms Op}{1-initialization.png}

\begin{frame}[fragile]
  \frametitle{Initialize Weights \& Bias Terms Op}
  \begin{python}
#################
### VARIABLES ###
#################

# all values are randomly assigned:
# sqrt(6 / (numInputNodes + numOutputNodes + 1))

weights = tf.Variable(tf.random_normal([numFeatures,numLabels],
          mean=0,
          stddev=(np.sqrt(6/numFeatures+numLabels+1)),
          name="weights"))

bias = tf.Variable(tf.random_normal([1,numLabels],
       mean=0,
       stddev=(np.sqrt(6/numFeatures+numLabels+1)),
       name="bias"))

# INITIALIZE our weights and biases
init_OP = tf.initialize_all_variables()
  \end{python}
\end{frame}

\framedgraphic{Apply Weights to Features Op}{2-apply-weights.png}

\begin{frame}[fragile]
  \frametitle{Apply Weights to Features Op}
  \begin{python}
apply_weights_OP = tf.matmul(X, weights, name="apply_weights")
  \end{python}
\end{frame}

\framedgraphic{Add Bias to Weighted Features Op}{3-add-bias.png}

\begin{frame}[fragile]
  \frametitle{Add Bias to Weighted Features Op}
  \begin{python}
add_bias_OP = tf.add(apply_weights_OP, bias, name="add_bias")
  \end{python}
\end{frame}

\framedgraphic{Activation Op}{4-apply-sigmoid.png}

\begin{frame}[fragile]
  \frametitle{Activation Op}
  \begin{python}
activation_OP = tf.nn.sigmoid(add_bias_OP, name="activation")
  \end{python}
\end{frame}

\framedgraphic{Evaluation Op: Mean Squared Error}{5-loss-function.png}

\begin{frame}[fragile]
  \frametitle{Evaluation Op: Mean Squared Error}
  \begin{python}
#####################
### EVALUATION OP ###
#####################

# COST FUNCTION i.e. MEAN SQUARED ERROR
cost_OP = tf.nn.l2_loss(activation_OP-yGold, name="squared_error_cost")  \end{python}
\end{frame}

\framedgraphic{Optimization Op: Gradient Descent}{6-optimization.png}

\begin{frame}[fragile]
  \frametitle{Optimization Op: Gradient Descent}
  \begin{python}
#######################
### OPTIMIZATION OP ###
#######################

# OPTIMIZATION ALGORITHM i.e. GRADIENT DESCENT
training_OP = tf.train.GradientDescentOptimizer(learningRate).minimize(cost_OP)
  \end{python}
\end{frame}

\begin{frame}[fragile]
  \frametitle{Run the Graph}
  \begin{python}
#####################
### RUN THE GRAPH ###
#####################

# Create a tensorflow session
sess = tf.Session()
# Initialize all tensorflow variables
sess.run(init_OP)

## Ops for vizualization
# argmax(activation_OP, 1) gives the label our model thought was most likely
# argmax(yGold, 1) is the correct label
correct_predictions_OP=tf.equal(tf.argmax(activation_OP,1),tf.argmax(yGold,1))
# False is 0 and True is 1, what was our average?
accuracy_OP = tf.reduce_mean(tf.cast(correct_predictions_OP, "float"))
# Summary op for regression output
activation_summary_OP = tf.histogram_summary("output", activation_OP)
# Summary op for accuracy
accuracy_summary_OP = tf.scalar_summary("accuracy", accuracy_OP)
# Summary op for cost
cost_summary_OP = tf.scalar_summary("cost", cost_OP)
# Summary ops to check how variables (W, b) are updating after each iteration
weightSummary = tf.histogram_summary("weights", weights.eval(session=sess))
biasSummary = tf.histogram_summary("biases", bias.eval(session=sess))
# Merge all summaries
all_summary_OPS = tf.merge_all_summaries()
# Summary writer
writer = tf.train.SummaryWriter("summary_logs", sess.graph_def)
  \end{python}
\end{frame}

\begin{frame}[fragile]
  \frametitle{Still 'Running the Graph'}
  \begin{python}
# Initialize reporting variables
cost = 0
diff = 1
# Training epochs
for i in range(numEpochs):
    if i > 1 and diff < .0001:
        print("change in cost %g; convergence."%diff)
        break
    else:
        # Run training step
        step = sess.run(training_OP, feed_dict={X: trainX, yGold: trainY})
        # Report occasional stats
        if i % 10 == 0:
            # Add epoch to epoch_values
            epoch_values.append(i)
            # Generate accuracy stats on test data
            summary_results, train_accuracy, newCost = sess.run(
                [all_summary_OPS, accuracy_OP, cost_OP],
                feed_dict={X: trainX, yGold: trainY}
            )
            # Add accuracy to live graphing variable
            accuracy_values.append(train_accuracy)
            # Add cost to live graphing variable
            cost_values.append(newCost)
            # Write summary stats to writer
            writer.add_summary(summary_results, i)
            # Re-assign values for variables
            diff = abs(newCost - cost)
            cost = newCost
  \end{python}
\end{frame}

\begin{frame}[fragile]
  \frametitle{Still 'Still Running the Graph'}
  \begin{python}
            #generate print statements
            print("step %d, training accuracy %g"%(i, train_accuracy))
            print("step %d, cost %g"%(i, newCost))
            print("step %d, change in cost %g"%(i, diff))

            # Plot progress to our two subplots
            accuracyLine, = ax1.plot(epoch_values, accuracy_values)
            costLine, = ax2.plot(epoch_values, cost_values)
            fig.canvas.draw()
            time.sleep(1)

# How well do we perform on held-out test data?
print("final accuracy on test set: %s" %str(sess.run(accuracy_OP,
                                                 feed_dict={X: testX,
                                                        yGold: testY})))
  \end{python}
\end{frame}

\begin{frame}[fragile]
  \frametitle{Reuse, Recycle}
  \begin{python}
##############################
### SAVE TRAINED VARIABLES ###
##############################

# Create Saver
saver = tf.train.Saver()
# Save variables to .ckpt file
# saver.save(sess, "trained_variables.ckpt")

# Close tensorflow session
sess.close()
  \end{python}
\end{frame}

\framedgraphic{}{thats-all-folks.jpg}

\end{document}


\section{Slotted ALOHA}\label{sec:saloha}
Slotted ALOHA~\cite{Roberts:1975:APS:1024916.1024920} is a \gls{tdma} protocol, that enable communication between nodes in a wireless network, by randomly selecting a time slot to transmit, while listening in every other time slot. This method of selecting time slots for transmitting will have a high probability of collisions happening, where multiple nodes transmit at the same time, which make this protocol an ideal candidate for simulating collisions and packet loss.

%An important part of any \gls{tdma} protocol is that only a single node should transmit at a given timeslot, otherwise collisions will occur. Thus, the Slotted ALOHA protocol is a good choice for
% TODO: Add number of arguments as parameter
\begin{algorithm}[ht]
    \DontPrintSemicolon
    \SetKwFunction{FSlottedALOHA}{SlottedALOHA}
    \SetKwProg{Fn}{procedure}{}{}

    \Fn{\FSlottedALOHA{S}}{
        secret $\leftarrow$ a single node picks a secret message\;

        \Repeat{\textit{1 hour}}{

            selected $\leftarrow$ randomly select a slot $\in$ {1, 2, \dots, S}\;

            \ForEach{current $\in$ {1, 2, \dots, S}}{
                \If{select = current}{
                    \If{node knows secret}{
                        duration $\leftarrow$ \texttt{Broadcast}(select)\;
                        \texttt{Sleep}(10s - duration)\;
                    }\Else{
                        \texttt{Sleep}(10s)\;
                    }
                }
                \Else{
                    \If{node knows secret}{
                        \texttt{Sleep}(10s)\;
                    }\Else{
                        secret $\leftarrow$ \texttt{Listen}(10s)\;
                    }
                }
            }
        }
    }

    \caption{The Slotted ALOHA protocol~\cite{Roberts:1975:APS:1024916.1024920}.}
    \label{algo:slottedaloha}
\end{algorithm}

The Slotted ALOHA protocol shown in \autoref{algo:slottedaloha} is a modified version of the protocol, where the goal is to share a secret message between every node a the network. Initially, a single random node picks a secret message, and the protocol begins. The protocol is designed to conserve energy by sleeping as much as possible. If the node knows the secret message, it will broadcast the message when its selected time slot comes up, and sleep in any other time slot. If the node does not know the secret message, it will sleep in its selected time slot, and listen for the message in any other time slot.

\subsection{Experiment}
We ran an experiment with the Slotted ALOHA protocol from \autoref{algo:slottedaloha}. The experiment was conducted on a network topology of 33 nodes generated from \acrshort{gps} location data, from a field test conducted in the Philippines. The topology can be found in \autoref{ch:app:aloha-topologies}. The goal of the experiment is to show the difference between virtual and real time, when running the protocol for an hour with a different number of time slots S.

\begin{table}[H]
    \begin{tabular}{|l|l|l|l|l|l|l|l|l|}
        \hline
        \diagbox{Time}{Slots (S)} & 5    & 6   & 7    & 8    & 9    & 10    & 11   & 12   \\ \hline
        Real                  & 45 s & 5 s & 90 s & 60 s & 50 s & 105 s & 60 s & 88 s \\ \hline
        %        Virtual               & 6h, 48 m & 5 h, 36 m & 4 h, 48 m & 4 h, 15 m& 3 h, 42 m&    &    & 2 h, 48m   \\ \hline
    \end{tabular}
    \caption{Real time results from running the ALOHA protocol with different total time slots.}
    \label{table:experiments:aloha-results}
\end{table}

\autoref{table:experiments:aloha-results} show the real time duration the simulation took to run the Slotted ALOHA with different parameters for the time slots S. We see that the shortest simulation took 5 seconds with 6 time slots, and the longest took 105 seconds with 10 time slots. This demonstrates the non-deterministic nature of the Slotted ALOHA protocol, where the time required to complete the simulation heavily depends on the number of colliding transmissions and lost packets. The main takeaway from this experiment is that we are able to run the hour long Slotted ALOHA protocol in less than two minutes, with 33 nodes.

%The results show that virtual time gives significant time savings, when running the simulations.

%Sleep real fast, listen real slow. Done.
%