\documentclass{article}
\usepackage[T2A]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{amsmath}
\usepackage{amsthm}
\usepackage{amsfonts}
\usepackage{mathtools}
\usepackage{algorithm}
\usepackage{algorithmicx}
\usepackage{algpseudocode}
\usepackage[left=75pt]{geometry}
\usepackage{tikz}

\newcommand{\score}[1]{\textrm{score}(#1)}
\newcommand{\bigO}[1]{\mathcal{O}{(#1)}}
\newcommand{\graph}[1]{\mathcal{#1}}
\newcommand{\ops}[1]{\textrm{ops}(#1)}
\newcommand{\expect}[1]{\mathbb{E} #1}
\newcommand{\argmin}{\operatornamewithlimits{argmin}}
\newcommand{\argmax}{\operatornamewithlimits{argmax}}

\author{Dmitry Lunin, \\ \small supervised by Senko O.V.}
\title{Improving speed efficiency of score-based Bayesian network structure learning algorithms}
\begin{document}
\maketitle
\tableofcontents
\pagebreak

\abstract{
	The task of Bayesian network structure learning is NP-hard \cite{StructureLearningIsNPComplete}, and as such it is usually solved by heuristic algorithms. That makes speed optimization of the structure learning algorithms especially important, since it allows to traverse more structures in a given time, yielding better quality answers.

	The proposed method improves speed efficiency of many structure learning algorithms by optimizing one of the most basic operations in score-based structure learning: the score evaluation and comparison.
}

\section{Structure Learning}
\subsection{Introduction}
\paragraph{The task} The aim of structure learning is to identify the Bayesian network structure (i.e. the graph) using data.

\paragraph{Applications}

The first application is knowledge discovery. We can use structure learning to find out (in)dependencies between variables in the data, or test our prior assumptions about them, obtaining better understanding of the data and the domain of knowledge.

The second application is off-the-shelf machine learning. In order to apply Bayesian network methods to a problem, firstly one needs to build a Bayesian network, which may require significant effort and domain expertise. On the other hand, many machine learning methods, for example random forests can be applied immediately, yielding adequate results which can be improved later by fine-tuning parameters. Advanced structure learning methods make it possible to apply such workflow to the Bayesian network methods.

\paragraph{Approaches} There are two main approaches to the structure learning task. The first, constraint-based approach, is based on doing statistical tests to obtain conditional independence statements, and build a Bayesian network that satisfies them. The point of the second approach, the score-based structure learning, is to introduce a metric of compatibility of a Bayesian network with the data, and then optimize it over the space of all Bayesian network structures. In this work, we focus on the score-based approach.

\subsection{Score-based approach}
\paragraph{Description} The idea of score-based approach is to associate a Bayesian network graph with a score, and then maximize it. Since the number of such graphs is very large, greedy optimization methods are often used.
\subsubsection{Decomposable scores}
A score is decomposable if it can be represented as a sum of scores of graph nodes:
\begin{equation}
\label{eq:decomposable_score}
\score{\graph{G}} = \sum_i{\score{X_i}}
\end{equation}
A decomposable score allows for fast recalculation of graph score after local operations on graph.
\subsubsection{Local operations}

\theoremstyle{definition}
\newtheorem*{local.operation}{Def}
\begin{local.operation}
	We call a graph operation \textbf{local} if it affects edges pointing to a constant number of nodes.
\end{local.operation}

\theoremstyle{definition}
\newtheorem*{operation.score}{Def}
\begin{operation.score}
	The \textbf{score} of a graph operation is defined as the difference between the graph scores after and before applying the operation.
	$$ \score{\textrm{op}} = \score{\graph{G}_{\textrm{after}}} - \score{\graph{G}_{\textrm{before}}} $$
\end{operation.score}

Usually the set of operations includes \textbf{edge addition}, \textbf{edge deletion} and \textbf{edge reversal}.

The advantage of using local operations in the structure search is that their (decomposable) scores can be computed efficiently, since they affect only a constant number of terms in the sum (\ref{eq:decomposable_score}). Edge affection and edge deletion affect 1 term and edge reversal affects 2 terms.

\subsubsection{Speed concerns}
The most expensive operation in the local search is the computation of $\score{X_i}$, especially when the amount of data is large. Hence, we want to minimize the number of such computations.

\subsection{Graph scores and mutual information}
\paragraph{Mutual Information} Mutual information is defined as:
\begin{equation}
I(X; Y) = \sum_{x \in X}{\sum_{y \in Y}{p(x, y)\,\log \frac{p(x,y)}{p(x)\,p(y)}\,dx\,dy}}
\end{equation}
It can also be expressed as $KL$-divergence between distributions $p(x, y)$ and $p(x)p(y)$:
\begin{equation}
I(X; Y) = D_{KL}(p(x, y)\,||\,p(x)p(y))
\end{equation}
Note that $p(x, y) = p(x)p(y)$, and therefore $I(X; Y) = 0$, when $X$ is independent of $Y$.

\paragraph{Application} Often computing graph scores for structure learning problem requires mutual information estimation. For example, BIC score. The reason behind this is that in discrete case, likelihood of a Bayesian network structure can be computed using mutual information:
\begin{equation}
\log p(\graph{G}|X) = N \sum_{i=1}^M{I(X_i; Pa(X_i))} - N \sum_{i=1}^M{H(X_i)}
\end{equation}
where $N$ is the number of data points, $M$ is the number of variables.
\paragraph{Entropy}
Mutual information, on the other hand, can be computed via entropy:
\begin{equation}
\label{eq:mi_via_entropy}
I(X; Y) = H(X) + H(Y) - H(X, Y)
\end{equation}
Where $H(X)$ is Shannon entropy:
\begin{equation}
H(X) = \sum_{x \in X}{p(x)\,\log p(x)\,dx}
\end{equation}
We use Equation \ref{eq:mi_via_entropy} for computing mutual information because it allows us to cache $H(X)$ instead of $I(X; Y)$; since it can be used for computing several $I(X; Y)$, this scheme is more efficient.

\subsection{Greedy Local Search}
\subsubsection{Algorithm description}
At each step of the algorithm, we choose the local operation with maximal score and apply it. The algorithm terminates where there are no operations that increase the score. That means that it has reached a local optimum (relative to the given score and local operations set).

\subsubsection{Improvements}
\paragraph{Storing operation scores in a heap} In order to find an operation with maximal score efficiently, we can use data structures such as a binary heap. That way, we can retrieve an operation with maximum score in $\bigO{1}$ time.

However, when we apply the operation, several problems arise. Firstly, some operations in the heap start violating acyclity constraints. This problem can be solved by checking for acyclity when the operation is retrieved from the heap.

Secondly, the score of some operations changes. The number of such operations is $\bigO{K}$. Hence removing and re-inserting them to the heap would require $\bigO{K \log{N_{op}}}$ time.

\paragraph{Tabu search} In order to avoid local maximums and plateaus, a list of recently applied operations can be stored. Operations from that list are not considered during a step of the greedy search.

\paragraph{Dataset perturbation} Another method for avoiding plateaus is to resample the dataset after a certain number of iterations.

\begin{algorithm}[t]
	\caption{Greedy Local Search algorithm}\label{euclid}
	\begin{algorithmic}[1]
		\Procedure{GreedyLocalSearch}{$\graph{G}_0, \score{\cdot}, \ops{\cdot}$}
		\State $\graph{G} \gets \graph{G}_0$
		\While{$\exists o \in \ops{\graph{G}}: \score{o} > 0$}
		\State $\displaystyle o \gets \argmax_{o \in \ops{\graph{G}}} {\score{o}}$
		\State $\graph{G} \gets o(\graph{G})$
		\EndWhile
		\State \textbf{return} $\graph{G}$
		\EndProcedure
	\end{algorithmic}
\end{algorithm}

\section{Fast score comparison}
\subsection{CPD posterior}
\paragraph{CPD estimation} Suppose we have a discrete random variable which takes on values $v_1, v_2, \ldots, v_m$ with probabilities $p_1, p_2, \ldots, p_m$ (these are the true probabilities). Now we have a dataset $\mathcal{D} = (x_1, x_2, \ldots, x_N)$, and we want to estimate the true probabilities $p_i$.

By the Bayes theorem,
\begin{equation}
p(p_1, \ldots, p_m | \mathcal{D}) = \frac{p(p_1, \ldots, p_m)}{p(\mathcal{D})} p(\mathcal{D} | p_1, \ldots, p_m)
\end{equation}

$p(\mathcal{D})$ is a constant w.r.t. $p_1, \ldots, p_m$.
\begin{multline}
p(\mathcal{D}|p_1, \ldots, p_m) = \prod_{i=1}^{N}{p(x_i|p_1, \ldots, p_m)} = \prod_{i=1}^{N}{p_{x_i}} = \prod_{i=1}^{N}{p_1^{[x_i = 1]} p_2^{[x_i = 2]} \ldots p_m^{[x_i = m]}} = \\ p_1^{\sum_{i=1}^N{[x_i = 1]}} p_2^{\sum_{i=1}^N{[x_i = 2]}} \ldots p_m^{\sum_{i=1}^N{[x_i = m]}} = p_1^{n_1} p_2^{n_2} \ldots p_m^{n_m} = \prod_{i = 1}^m{p_i^{n_i}}
\end{multline}

We assume that our prior on the probabilities is a Dirichlet distribution, i.e. it has the form
\begin{equation*}
p(p_1, \ldots, p_m) \sim \textrm{Dirichlet}(\alpha_1, \alpha_2, \ldots, \alpha_m)
\end{equation*}

\begin{equation}
p(p_1, \ldots, p_m) = \frac{1}{B(\alpha_1, \alpha_2, \ldots, \alpha_m)} \prod_{i=1}^m{p_i^{\alpha_i - 1}}
\end{equation}

The uniform prior corresponds to $\alpha_i = 1$ assignment.

Combining these equations, we have that the posterior over $p_1, p_2, \ldots, p_m$ is also a Dirichlet distribution
\begin{multline}
p(p_1, p_2, \ldots, p_m|\mathcal{D}) = \frac{1}{Z_1}\,p(p_1, \ldots, p_m)\,p(\mathcal{D}|p_1, \ldots, p_m) = \\ \frac{1}{Z_2} \, \prod_{i=1}^m{p_i^{\alpha_i - 1}} \, \prod_{i=1}^m{p_i^{n_i}} = \frac{1}{Z_2}{ \prod_{i=1}^m{p_i^{n_i + \alpha_i - 1}}}
\end{multline}

\begin{equation*}
p(p_1, p_2, \ldots, p_m|\mathcal{D}) \sim \textrm{Dirichlet}(\alpha_1 + n_1, \alpha_2 + n_2, \ldots, \alpha_m + n_m)
\end{equation*}

\subsection{Dirichlet distribution properties}

\paragraph{Probability density function}
\begin{equation}
p(p_1, \ldots, p_m) = \frac{1}{B(\alpha_1, \alpha_2, \ldots, \alpha_m)} \prod_{i=1}^m{p_i^{\alpha_i - 1}}
\end{equation}

\paragraph{Support}
\begin{equation}
p_1 + p_2 + \ldots + p_m = 1
\end{equation}

\paragraph{Marginals}
\begin{equation*}
\alpha_0 = \sum_{i=1}^m{\alpha_i}
\end{equation*}

\begin{equation*}
p(p_i) \sim \textrm{Beta}(\alpha_i, \alpha_0 - \alpha_i)
\end{equation*}

\begin{equation}
p(p_i) = \frac{1}{B(\alpha_i, \alpha_0 - \alpha_i)} \, p_i^{\alpha_i} (1 - p_i)^{\alpha_0 - \alpha_i}
\end{equation}

\paragraph{Mean}
\begin{equation}
\expect{p_i} = \frac{\alpha_i}{\alpha_0} = \frac{\alpha_i}{\sum\limits_{j=1}^m{\alpha_j}}
\end{equation}

\paragraph{Variance}
\begin{equation}
\mathbb{D}{p_i} = \frac{\alpha_i(\alpha_0 - \alpha_i)}{\alpha_0^2(\alpha_0 + 1)}
\end{equation}

\paragraph{Covariance}
\begin{equation}
\textrm{cov}(p_i, p_j) = \frac{-\alpha_i\alpha_j}{\alpha_0^2(\alpha_0 + 1)}
\end{equation}

\subsection{Theorems}

\newtheorem{theorem}{Theorem}
\begin{theorem}
	If $p_1, p_2, \ldots, p_m \sim \textrm{Dirichlet}(\alpha_1, \alpha_2, \ldots, \alpha_n)$, $x = p_i$, $\alpha_x = \alpha_i$, $y = p_j$, $\alpha_y = \alpha_j$ and $k_x, k_y, m_x, m_y$ are arbitrary positive constants, then
	\begin{multline}
	\mathbb{E}(x^{k_x} y^{k_y} \log^{m_x} x \log^{m_y} y) = \\ \frac{1}{B(\alpha_x, \alpha_y, \alpha_z)} \,  \sum_{i=0}^{m_y}{ C^i_{m_y} \frac{\partial^{m_y-i} B(\alpha_y + k_y, \alpha_z)}{(\partial \alpha_y)^{m_y-i}} \, \frac{\partial^{m_x + i}}{(\partial \alpha_x)^{m_x} (\partial \alpha_y)^{i}} \, B(\alpha_x + k_x, \alpha_y + \alpha_z + k_y)}
	\end{multline}

	where $\alpha_z = \alpha_0 - \alpha_x - \alpha_y$
	\begin{proof}
		Let $z$ be the combined probability of all values $v_k$ except $v_i$ and $v_j$. Then

		\begin{equation*}
		x, y, z \sim \textrm{Dirichlet}(\alpha_x, \alpha_y, \alpha_z)
		\end{equation*}

		\begin{equation}
		p(x, y, z) = \frac{1}{B(\alpha_x, \alpha_y, \alpha_z)} x^{\alpha_x - 1} y^{\alpha_y - 1} z^{\alpha_z - 1}
		\end{equation}

		$x + y + z = 1$, so $z$ is a deterministic function of $x$ and $y$:

		\begin{equation}
		p(x, y) = \frac{1}{B(\alpha_x, \alpha_y, \alpha_z)} x^{\alpha_x - 1} y^{\alpha_y - 1} (1 - x - y)^{\alpha_z - 1}
		\end{equation}

		\begin{multline*}
		\mathbb{E}(x^{k_x} y^{k_y} \log^{m_x} x \log^{m_y} y) = \int\limits_{0 < x + y < 1} {p(x, y) \, x^{k_x} y^{k_y} \log^{m_x} x \log^{m_y} y \, dx \, dy} =
		\\ \int\limits_{0 < x + y < 1} {\frac{1}{B(\alpha_x, \alpha_y, \alpha_z)} x^{\alpha_x - 1} y^{\alpha_y - 1} (1 - x - y)^{\alpha_z - 1} \, x^{k_x} y^{k_y} \log^{m_x} x \log^{m_y} y \, dx \, dy} =
		\\ \frac{1}{B(\alpha_x, \alpha_y, \alpha_z)} \int\limits_{0 < x + y < 1} { x^{\alpha_x + k_x - 1} y^{\alpha_y + k_y - 1} (1 - x - y)^{\alpha_z - 1} \, \log^{m_x} x \log^{m_y} y \, dx \, dy} =
		\\ \frac{1}{B(\alpha_x, \alpha_y, \alpha_z)} \int\limits_0^1 { x^{\alpha_x + k_x - 1} \log^{m_x}{x} \, dx \, \int\limits_0^{1-x}{ y^{\alpha_y + k_y - 1} (1 - x - y)^{\alpha_z - 1} \, \log^{m_y} y \, dy}} =
		\\  \frac{1}{B(\alpha_x, \alpha_y, \alpha_z)} \int\limits_0^1 { x^{\alpha_x + k_x - 1} \log^{m_x}{x} \, dx \, \int\limits_0^{1-x}{ \frac{\partial^{m_y}}{(\partial \alpha_y)^{m_y}} (y^{\alpha_y + k_y - 1} (1 - x - y)^{\alpha_z - 1}) \, dy}} =
		\\ \frac{1}{B(\alpha_x, \alpha_y, \alpha_z)} \int\limits_0^1 { x^{\alpha_x + k_x - 1} \log^{m_x}{x} \, dx \, \frac{\partial^{m_y}}{(\partial \alpha_y)^{m_y}} \int\limits_0^{1-x}{  (y^{\alpha_y + k_y - 1} (1 - x - y)^{\alpha_z - 1}) \, dy}}
		\end{multline*}

		Now let's compute $I(x) = \int\limits_0^{1-x}{  (y^{\alpha_y + k_y - 1} (1 - x - y)^{\alpha_z - 1}) \, dy} $. Let $y = (1 - x)t$, then

		\begin{multline*}
		I(x) = \int\limits_0^1{((1 - x)t)^{\alpha_y + k_y - 1} (1 - x - (1 - x)t)^{\alpha_z - 1} \, d((1 - x)t)} = \\ \int\limits_0^1{(1 - x)^{\alpha_y + \alpha_z + k_y - 1} \, t^{\alpha_y + k_y - 1} (1 - t)^{\alpha_z - 1} \, dt} = \\ (1 - x)^{\alpha_y + \alpha_z + k_y - 1} \int\limits_0^1{t^{\alpha_y + k_y - 1} (1 - t)^{\alpha_z - 1} \, dt} = (1 - x)^{\alpha_y + \alpha_z + k_y - 1} B(\alpha_y + k_y, \alpha_z)
		\end{multline*}

		\begin{multline*}
		\mathbb{E}(x^{k_x} y^{k_y} \log^{m_x} x \log^{m_y} y) = \\ \frac{1}{B(\alpha_x, \alpha_y, \alpha_z)} \int\limits_0^1 { x^{\alpha_x + k_x - 1} \log^{m_y}{x} \, \frac{\partial^{m_y} (1 - x)^{\alpha_y + \alpha_z + k_y - 1} B(\alpha_y + k_y, \alpha_z)}{(\partial \alpha_y)^{m_y}} \, dx } =
		\\ \sum_{i=0}^{m_y}{ C^i_{m_y} \frac{1}{B(\alpha_x, \alpha_y, \alpha_z)} \, \frac{\partial^{m_y-i} B(\alpha_y + k_y, \alpha_z)}{(\partial \alpha_y)^{m_y-i}} \, \int\limits_0^1 { x^{\alpha_x + k_x - 1} \log^{m_x}{x} \, (1 - x)^{\alpha_y + \alpha_z + k_y - 1} \, \log^i{(1 - x)} dx }} =
		\\ \sum_{i=0}^{m_y}{ \frac{C^i_{m_y}}{B(\alpha_x, \alpha_y, \alpha_z)} \, \frac{\partial^{m_y-i} B(\alpha_y + k_y, \alpha_z)}{(\partial \alpha_y)^{m_y-i}} \, \int\limits_0^1 { x^{\alpha_x + k_x - 1} \log^{m_x}{x} \, (1 - x)^{\alpha_y + \alpha_z + k_y - 1} \, \log^i{(1 - x)} dx }} =
		\\ \sum_{i=0}^{m_y}{ \frac{C^i_{m_y}}{B(\alpha_x, \alpha_y, \alpha_z)} \, \frac{\partial^{m_y-i} B(\alpha_y + k_y, \alpha_z)}{(\partial \alpha_y)^{m_y-i}} \, \int\limits_0^1 { \frac{\partial^{m_x}}{(\partial \alpha_x)^{m_x}} (x^{\alpha_x + k_x - 1} \, (1 - x)^{\alpha_y + \alpha_z + k_y - 1} \, \log^i{(1 - x)}) \, dx }} =
		\\ \sum_{i=0}^{m_y}{ \frac{C^i_{m_y}}{B(\alpha_x, \alpha_y, \alpha_z)} \, \frac{\partial^{m_y-i} B(\alpha_y + k_y, \alpha_z)}{(\partial \alpha_y)^{m_y-i}} \, \frac{\partial^{m_x}}{(\partial \alpha_x)^{m_x}} \, \int\limits_0^1 {x^{\alpha_x + k_x - 1} \, (1 - x)^{\alpha_y + \alpha_z + k_y - 1} \, \log^i{(1 - x)} \, dx }} =
		\\ \sum_{i=0}^{m_y}{ \frac{C^i_{m_y}}{B(\alpha_x, \alpha_y, \alpha_z)} \, \frac{\partial^{m_y-i} B(\alpha_y + k_y, \alpha_z)}{(\partial \alpha_y)^{m_y-i}} \, \frac{\partial^{m_x}}{(\partial \alpha_x)^{m_x}} \,
			\frac{\partial^{i}}{(\partial \alpha_y)^{i}} \, \int\limits_0^1 {x^{\alpha_x + k_x - 1} \, (1 - x)^{\alpha_y + \alpha_z + k_y - 1} \, dx }} =
		\\ \frac{1}{B(\alpha_x, \alpha_y, \alpha_z)} \,  \sum_{i=0}^{m_y}{ C^i_{m_y} \frac{\partial^{m_y-i} B(\alpha_y + k_y, \alpha_z)}{(\partial \alpha_y)^{m_y-i}} \, \frac{\partial^{m_x + i}}{(\partial \alpha_x)^{m_x} (\partial \alpha_y)^{i}} \, B(\alpha_x + k_x, \alpha_y + \alpha_z + k_y)}
		\end{multline*}
	\end{proof}
\end{theorem}

\begin{theorem}
	If $x \sim \textrm{Beta}(\alpha_x, \alpha_y)$, $y = 1 - x$ and $k_x, k_y, m_x, m_y$ are arbitrary positive constants, then
	\begin{equation}
	\mathbb{E}(x^{k_x} y^{k_y} \log^{m_x} x \log^{m_y} y) = \frac{1}{B(\alpha_x, \alpha_y)} \, \frac{\partial^{m_x + m_y} \, B(\alpha_x + k_x, \alpha_y + k_y)}{(\partial \alpha_x)^{m_x} (\partial \alpha_y)^{m_y}}
	\end{equation}
	\begin{proof}

		\begin{multline*}
		\mathbb{E}(x^{k_x} y^{k_y} \log^{m_x} x \log^{m_y} y) =
		\frac{1}{B(\alpha_x, \alpha_y)} \, \int\limits_0^1{p(x) x^{k_x} y^{k_y} \log^{m_x} x \log^{m_y} y dx} =
		\\ \int\limits_0^1{x^{\alpha_x + k_x - 1} y^{\alpha_y + k_y - 1} \log^{m_x} x \log^{m_y} y \, dx} =
		\\ \frac{1}{B(\alpha_x, \alpha_y)} \, \int\limits_0^1{x^{\alpha_x + k_x - 1} (1 - x)^{\alpha_y + k_y - 1} \log^{m_x} x \log^{m_y} (1 - x) \, dx} =
		\\ \frac{1}{B(\alpha_x, \alpha_y)} \, \int\limits_0^1{ \frac{\partial^{m_x}}{(\partial \alpha_x)^{m_x}} \, (x^{\alpha_x + k_x - 1} (1 - x)^{\alpha_y + k_y - 1} \log^{m_y} (1 - x)) \, dx} =
		\\ \frac{1}{B(\alpha_x, \alpha_y)} \, \int\limits_0^1{ \frac{\partial^{m_x + m_y}}{(\partial \alpha_x)^{m_x} (\partial \alpha_y)^{m_y}} \, (x^{\alpha_x + k_x - 1} (1 - x)^{\alpha_y + k_y - 1}) \, dx} =
		\\ \frac{1}{B(\alpha_x, \alpha_y)} \, \frac{\partial^{m_x + m_y}}{(\partial \alpha_x)^{m_x} (\partial \alpha_y)^{m_y}} \, \int\limits_0^1{  (x^{\alpha_x + k_x - 1} (1 - x)^{\alpha_y + k_y - 1}) \, dx} =
		\frac{1}{B(\alpha_x, \alpha_y)} \, \frac{\partial^{m_x + m_y} B(\alpha_x + k_x, \alpha_y + k_y)}{(\partial \alpha_x)^{m_x} (\partial \alpha_y)^{m_y}}
		\end{multline*}
	\end{proof}
\end{theorem}

\begin{theorem}
	If $p_1, p_2, \ldots, p_m \sim \textrm{Dirichlet}(\alpha_1, \alpha_2, \ldots, \alpha_n)$, $x = p_i$, $\alpha_x = \alpha_i$, $y = p_j$, $\alpha_y = \alpha_j$, then

	\begin{multline*}
	\mathbb{E}(x^{k_x}\, y^{k_y} \log^{m_x}{x} \, \log^{m_y}{y} \, \log(x + y)) =
	\\ -\frac{1}{B(\alpha_x, \alpha_y, \alpha_z)} \, \sum_{n=1}^{\infty}{\frac{1}{n} \sum_{i=0}^{m_y}{ C^i_{m_y} \frac{\partial^{m_y-i} B(\alpha_y + k_y, \alpha_z + n)}{(\partial \alpha_y)^{m_y-i}} \, \frac{\partial^{m_x + i}}{(\partial \alpha_x)^{m_x} (\partial \alpha_y)^{i}} \, B(\alpha_x + k_x, \alpha_y + \alpha_z + n + k_y)}}
	\end{multline*}

	\begin{proof}

		\begin{multline}
		\mathbb{E}(x^{k_x}\, y^{k_y} \log^{m_x}{x} \, \log^{m_y}{y} \, \log(x + y)) =
		\\ \int\limits_{0 < x + y < 1}{\frac{1}{B(\alpha_x, \alpha_y, \alpha_z)} \, x^{k_x + \alpha_x - 1} y^{k_y + \alpha_y - 1} (1 - x - y)^{\alpha_z - 1} \, \log(x + y) \, \log^{m_x}{x} \, \log^{m_y}{y} \, dx \, dy} =
		\\ \frac{1}{B(\alpha_x, \alpha_y, \alpha_z)} \, \int\limits_{0 < x + y < 1}{x^{k_x + \alpha_x - 1} y^{k_y + \alpha_y - 1} (1 - x - y)^{\alpha_z - 1} \, \log(1 - (1 - x - y)) \, \log^{m_x}{x} \, \log^{m_y}{y} \, dx \, dy} =
		\\ \frac{1}{B(\alpha_x, \alpha_y, \alpha_z)} \, \int\limits_{0 < x + y < 1}{x^{k_x + \alpha_x - 1} y^{k_y + \alpha_y - 1} (1 - x - y)^{\alpha_z - 1} \, \log(-\sum_{n=1}^{\infty}{\frac{(1 - x - y)^n}{n}}) \, \log^{m_x}{x} \, \log^{m_y}{y} \, dx \, dy} =
		\\-\frac{1}{B(\alpha_x, \alpha_y, \alpha_z)} \, \sum_{n=1}^{\infty}{\frac{1}{n} \int\limits_{0 < x + y < 1}{x^{k_x + \alpha_x - 1} y^{k_y + \alpha_y - 1} (1 - x - y)^{n + \alpha_z - 1} \, \log^{m_x}{x} \, \log^{m_y}{y} \, dx \, dy}}
		\end{multline}

		Note that the integral has the same form as in the proof of Theorem 1, so we have

		\begin{multline*}
		\mathbb{E}(x^{k_x}\, y^{k_y} \log^{m_x}{x} \, \log^{m_y}{y} \, \log(x + y)) =
		\\ -\frac{1}{B(\alpha_x, \alpha_y, \alpha_z)} \, \sum_{n=1}^{\infty}{\frac{1}{n} \sum_{i=0}^{m_y}{ C^i_{m_y} \frac{\partial^{m_y-i} B(\alpha_y + k_y, \alpha_z + n)}{(\partial \alpha_y)^{m_y-i}} \, \frac{\partial^{m_x + i}}{(\partial \alpha_x)^{m_x} (\partial \alpha_y)^{i}} \, B(\alpha_x + k_x, \alpha_y + \alpha_z + n + k_y)}}
		\end{multline*}

	\end{proof}
\end{theorem}

\subsection{Entropy variance}
\paragraph{Entropy} Recall that the entropy has the form
\begin{equation*}
H(p_1, p_2, \ldots, p_m) = \sum_{i = 1}^m{p_i \log p_i}
\end{equation*}

We want to compute the variance of our estimate of the entropy $\mathbb{D}H(p_1, p_2, \ldots, p_m)$, where $p_1, p_2, \ldots, p_m \sim \textrm{Dirichlet}(\alpha_1 + n_1, \ldots, \alpha_m + n_m)$, as discussed above.

\begin{equation}
\mathbb{D}(\sum_{i = 1}^n{X_i}) = \sum_{i=1}^n{\mathbb{D}X_i} + 2 \sum_{i = 1}^n{\sum_{j = 1, \\ j < i}^n{{\textrm{cov}(X_i, X_j)}}}
\end{equation}

Applying this formula to our task, we have that
\begin{equation}
\mathbb{D}(\sum_{i = 1}^n{p_i \log{p_i}}) = \sum_{i=1}^n{\mathbb{D}(p_i \log{p_i})} + 2 \sum_{i = 1}^n{\sum_{j = 1, \\ j < i}^n{{\textrm{cov}(p_i \log{p_i}, p_j \log{p_j})}}}
\end{equation}

A well-known fact from probability theory states that
\begin{equation}
\mathbb{D}X = \mathbb{E}(X - \mathbb{E}X)^2 = \mathbb{E}(X^2 - 2X \mathbb{E}X - (\mathbb{E}X)^2) = \mathbb{E}(X^2) - (\mathbb{E}X)^2
\end{equation}

\begin{multline}
\textrm{cov}(X, Y) = \mathbb{E}(X - \mathbb{E}X)(Y - \mathbb{E}Y) = \mathbb{E}(XY - X \mathbb{E}Y - Y \mathbb{E}X + \mathbb{E}X\mathbb{E}Y) = \mathbb{E}XY - \mathbb{E}X\mathbb{E}Y
\end{multline}

Applying,
\begin{equation}
\mathbb{D}(p_i \log{p_i}) = \mathbb{E}(p_i^2 \log^2{p_i}) - (\mathbb{E} \, p_i \log{p_i})^2
\end{equation}
\begin{equation}
\textrm{cov}(p_i \log{p_i}, p_j \log{p_j}) = \mathbb{E}(p_i p_j \log{p_i} \log{p_j}) - (\mathbb{E} \, p_i \log{p_i})(\mathbb{E} \, p_j \log{p_j})
\end{equation}

Note that all values on the right side can be computed using Theorem 1 or Theorem 2. Hence, we have an closed-form expression for $\mathbb{D}H(p_1, p_2, \ldots, p_m)$.

\subsection{Mutual information variance}
Mutual information can be expressed as
\begin{equation}
MI(X, Y) = H(X) + H(Y) - H(X, Y)
\end{equation}
where $X$ and $Y$ are some sets of random variables.

In local structure search, we need to estimate
\begin{equation}
MI(X, Pa(X)) = H(X) + H(Pa(X)) - H(X, Pa(X))
\end{equation}

While doing structure search, we can easily precompute $H(X)$ on the entire dataset; estimating that term on a subset of the data doesn't make much sense. So we consider $H(X)$ to be a fixed constant as an approximation, which is reasonable because it's variance is very small (it is an entropy over only one variable that is computed using the entire dataset).

\begin{equation*}
\mathbb{D}(MI(X, Pa(X))) \approx \mathbb{D}(H(Pa(X)) - H(X, Pa(X)))
\end{equation*}

In terms of $p_{11}, p_{12}, \ldots, p_{nm}$ -- probabilities of instantiations of $(X, Pa(X))$:
\begin{equation*}
H(Pa(X)) - H(X, Pa(X)) = -\sum_j{(\sum_i{p_{ij}}) \log(\sum_i{p_{ij}})} + \\ \sum_{i,j}{p_{ij} \log p_{ij}}
\end{equation*}

\begin{equation*}
\mathbb{D}(H(Pa(X)) - H(X, Pa(X))) = \mathbb{D}H(Pa(X)) + \mathbb{D}H(X, Pa(X)) - 2\,\mathrm{cov}(H(Pa(X)), H(X, Pa(X)))
\end{equation*}

Variances $\mathbb{D}H(Pa(X))$ and $\mathbb{D}H(X, Pa(X))$ can be computed as in the previous section. Now consider $\mathrm{cov}(H(Pa(X)), H(X, Pa(X)))$:

\begin{multline}
\mathrm{cov}(H(Pa(X)), H(X, Pa(X))) = \mathrm{cov}(\sum_j{(\sum_i{p_{ij}}) \log(\sum_i{p_{ij}})}, \sum_{i,j}{p_{ij} \log p_{ij}}) =
\\ \sum_a \sum_{b,c} \mathrm{cov}((\sum_i{p_{ia}}) \log(\sum_i{p_{ia}}), p_{bc} \log p_{bc})
\end{multline}

\begin{multline}
\mathrm{cov}((\sum_i{p_{ia}}) \log(\sum_i{p_{ia}}), p_{bc} \log p_{bc}) = \mathbb{E}((\sum_i{p_{ia}}) \log(\sum_i{p_{ia}}) \, p_{bc} \log p_{bc}) - \mathbb{E}((\sum_i{p_{ia}}) \log(\sum_i{p_{ia}})) \mathbb{E}(p_{bc} \log p_{bc})
\end{multline}

The first term can be computed by applying Theorem 3 in case $a = c$:
\begin{multline}
\mathbb{E}((\sum_i{p_{ia}}) \log(\sum_i{p_{ia}}) \, p_{ba} \log p_{ba}) = \mathbb{E}((p_{ba} + \sum_{i \neq b}{p_{ia}}) \log(p_{ba} + \sum_{i \neq b}{p_{ia}}) \, p_{ba} \log p_{ba}) = \\
\mathbb{E}(p_{ba}^2 \log(p_{ba} + \sum_{i \neq b}{p_{ia}}) \log p_{ba}) + \mathbb{E}((\sum_{i \neq b}{p_{ia}}) \log(p_{ba} + \sum_{i \neq b}{p_{ia}}) \, p_{ba} \log p_{ba}), \,\,\, \mathrm{where} \,\,\, x = p_{ba}, \, y = \sum_{i \neq b}{p_{ia}}
\end{multline}

Or by applying Theorem 1 or Theorem 2 otherwise: $x = p_{bc}, y = \sum_i{p_{ia}}$.

The second term can also be computed using Theorem 1 or Theorem 2.

\subsection{Score difference}
\paragraph{BIC score} A popular score function choice is the Bayesian Information Criterion (BIC) \cite{BICScore}:
\begin{equation}
\textrm{score}_{BIC}(\graph{G}) = \mathit{l}(\graph{G} | \mathcal{D}) - \frac{\log{N}}{2} \textrm{Dim}[\graph{G}] = N \sum_{i=1}^M MI(X_i, \textrm{Pa}(X_i)) + N \sum_{i=1}^M H(X_i) - \frac{\log{N}}{2} \textrm{Dim}[\graph{G}]
\end{equation}

The second term doesn't depend on the network structure, and the last doesn't depend on the data. Hence, we need to consider only the first term (which was done in the previous section).

\paragraph{Edge addition and deletion} Consider addition of an edge from $X_j$ to $X_i$.
\begin{multline*}
\mathbb{D}(\,\score{X_i; \textrm{Pa}(X_i) \cup \{X_j\}} - \score{X_i; \textrm{Pa}(X_i)}) =
\\ \mathbb{D}(H(X_i) + H(\textrm{Pa}(X_i), X_j) - H(X_i, \textrm{Pa}(X_i), X_j) - H(X_i) - H(\textrm{Pa}(X_i)) + H(X_i, \textrm{Pa}(X_i))) =
\\ \mathbb{D}(H(\textrm{Pa}(X_i), X_j) - H(X_i, \textrm{Pa}(X_i), X_j) - H(\textrm{Pa}(X_i)) + H(X_i, \textrm{Pa}(X_i)))
\end{multline*}

In order to this variance, we need to know:
\begin{enumerate}
	\item Variances of individual terms (computed in 2.4)
	\item These covariances can be computed as in 2.5 (one set of variables in the entropy is a subset of another):
	\\ $cov(H(\textrm{Pa}(X_i), X_j), H(X_i, \textrm{Pa}(X_i), X_j))$,
	\\ $cov(H(\textrm{Pa}(X_i), X_j),  H(\textrm{Pa}(X_i)))$,
	\\ $cov(H(X_i, \textrm{Pa}(X_i), X_j), H(\textrm{Pa}(X_i)))$,
	\\ $cov(H(X_i, \textrm{Pa}(X_i), X_j), H(X_i, \textrm{Pa}(X_i)))$
	\\ $cov(H(\textrm{Pa}(X_i)), H(X_i, \textrm{Pa}(X_i)))$

	\item $cov(H(\textrm{Pa}(X_i), X_j), H(\textrm{Pa}(X_i), X_i)$, which can't be computed that way.
\end{enumerate}

In order to get an upper bound on $cov(H(\textrm{Pa} (X_i), X_j), H(\textrm{Pa}(X_i), X_i)$, we can use the following statement (via Cauchy–Schwarz inequality):
\begin{equation}
|cov(X, Y)| \le \sqrt{\mathbb{D}X \, \mathbb{D}Y}
\end{equation}

\paragraph{Edge reversal} Edge reversal score variance upper bound can be derived in the same way. Also note that it can be represented as a combination of edge deletion and edge addition.

\section{Improved Greedy Search}
\subsection{Overview}
We focus on the Greedy Local Search algorithm for the following reasons:
\begin{itemize}
	\item It is conceptually simple, but effective. In a large comparative study \cite{MinMaxHillClimbing} its (with certain improvements discussed in Section 1) performance was shown to be on par with other state-of-the-art algorithms.
	\item It is sometimes used as a sub-procedure in more complex structure learning algorithms, such as Min-Max Hill Climbing.
	\item It is very likely that it benefits the most from the proposed improvement. While other algorithms can, for example, employ constraint-based structure learning techniques, Greedy Local Search fully relies on score comparison queries.
\end{itemize}

Estimation of the variance of the operation scores difference allows to estimate \\ $P(\score{\textrm{op}_a} < \score{\textrm{op}_b} | \mathcal{D})$ using Chebyshev inequality.

\subsection{Finding maximum score}
\paragraph{The task} On each step of the Greedy Local Search algorithm, we need to find an operation with the largest score. It can be easily done by linear search in one pass. Now we want to improve the speed of such procedure, while
\begin{itemize}
	\item getting the correct answer with probability $ \ge 1 - p_0 $.
	\item retaining $\bigO{N_{op}}$ complexity of the algorithm.
\end{itemize}
\paragraph{The algorithm} The algorithm, which we call Stochastic Linear Search, proceeds as follows. As in the ordinary linear search, we consider operations one by one, while maintaining the current maximum. The only difference is that instead of directly comparison of scores computed on the entire dataset, $\textrm{MaxUntilSuccess}$ sub-procedure is used. It either returns the comparison result, or fails if there is not enough data to reliably compare scores.

\begin{algorithm}[t]
	\caption{Stochastic Linear Search}\label{euclid}
	\begin{algorithmic}[1]
		\Procedure{MaxUntilSuccess}{$\textrm{op}_1$, $\textrm{op}_2$, $p_0$, $N_{init}$, $N_{batch}$, $\mathcal{D}$}
		\State $N_{cur} \gets N_{init}$
		\While{$N_{cur} < N$}
		\If{$P(\score{\textrm{op}_1} > \score{\textrm{op}_2} \, | \, \mathcal{D}[:N_{cur}]) > p_0$}
			\Return $(\score{\textrm{op}_1} > \score{\textrm{op}_2})$
		\Else \If{$P(\score{\textrm{op}_1} < \score{\textrm{op}_2} \, | \, \mathcal{D}[:N_{cur}]) > p_0$}
		\Return $(\score{\textrm{op}_1} < \score{\textrm{op}_2})$
		\EndIf
		\EndIf
		\State $N_{cur} \gets N_{cur} + N_{batch}$
		\EndWhile

		\Return error
		\EndProcedure
		\\

		\Procedure{StochasticLinearSearch}{$\textrm{ops}$, $p_0$, $N_{init}$, $N_{batch}$, $\mathcal{D}$}
		\State $m \gets \textrm{None}$
		\For{$x \in \textrm{ops}$}
		\State $m \gets MaxUntilSuccess(\frac{p_0}{n}, m, x, N_{init}, N_{batch}, \mathcal{D}) $
		\If{$m = \textrm{error}$}
			\Return error
		\EndIf

		\EndFor

		\Return $m$
		\EndProcedure
	\end{algorithmic}
\end{algorithm}

\subsection{Modified greedy search algorithm}
The only change to the Greedy Local Search algorithm is that instead of simply finding an operation with maximal score the Stochastic Linear Search is used.

\paragraph{Error probability} As a consequence, on each step of the greedy search, there is (at most) $p_0$ probability to make a suboptimal operation choice. We could try to get an upper bound on the probability of the error of the entire algorithm run, however, it would likely be overestimated. The Chebyshev inequality upper bound of $P(\score{\textrm{op}_a} < \score{\textrm{op}_b} | \mathcal{D})$ is also an overestimation: experiments show that the distribution over operation scores are rather close to normal. On the other hand, we usually don't need precise local greedy search run results per se; rather, we need as high resulting network score as possible, and the fact that it is indeed a local maximum w.r.t. chosen local operations. \textbf{Concluding, it makes sense to leave $p_0$ as an algorithm parameter that controls the accuracy-speed tradeoff}.

\section{Conclusion}
In this work, an optimization of Bayesian network score comparison was proposed, which allows to enhance speed of structure learning algorithms that rely on network score evaluations (i.e. score-based approach methods). It was done by deriving variance of the plug-in entropy and mutual information estimator (which may be a useful result in itself). The necessary modifications to the Greedy Local Search procedure were described.

\paragraph{Future work}
\begin{itemize}
	\item \textbf{Empirical comparison of the proposed algorithm to the existing ones}.
	\item \textbf{Working with heap} One of the common speed optimizations of the Greedy Local Search is storing operations in a heap. In order to use it alongside the proposed method, a stochastic version of heap is required (like the stochastic version of linear search is used in the current version).
	\item \textbf{Applying the technique to other score-based algorithms} While for some algorithms, like MMHC, it is as simple as plugging in the modified Greedy Search algorithm, others, like GES require further research.
	\end{itemize}

\begin{thebibliography}{9}

	\bibitem{KollerFriedman}
	Daphne Koller, Nir Friedman
	\emph{Probabilistic Graphical Models: Principles and Techniques},
	The MIT Press, Cambridge, Massachusetts,
	2009.

	\bibitem{LocalSearch}
	David Heckerman, Dan Geiger, David M. Chickering
	\emph{Learning Bayesian Networks: The Combination of Knowledge and Statistical Data}, 1995

	\bibitem{LocalSearchOrigin}
	Edward Herskovits, Gregory Cooper
	\emph{Kutato: An Entropy-Driven System for Construction of Probabilistic Expert Systems from Databases}

	\bibitem{MDLScore}
	Lam and F. Bacchus
	\emph{Learning Bayesian belief networks: An approach based on the MDL principle}

	\bibitem{BICScore}
	Barron, Rissanen, Yu
	\emph{The minimum description length principle in coding
	and modeling}, 1998

	\bibitem{StructureLearningIsNPComplete}
	David M. Chickering.
	\emph{Learning Bayesian networks is NP-complete}

	\bibitem{AsymptoticStructureLearningIsNPHard}
	David M. Chickering, Christopher  Meek, David Heckerman.    \emph{Large-sample   learning   of
	Bayesian networks is NP-hard}

	\bibitem{MeekConjecture}
	David M. Chickering
	\emph{Optimal Structure Identification With Greedy Search}, Journal of Machine Learning Research, 2002

	\bibitem{MinMaxHillClimbing}
	Ioannis Tsamardinos, Laura E. Brown, Constantin F. Aliferis
	\emph{The max-min hill-climbing Bayesian network
	structure learning algorithm}, 2006

	\bibitem{GESLargeSampleOptimality}
	David M. Chickering, Cristopher Meek
	\emph{Finding Optimal Bayesian Networks}, UAI, 2002

	\bibitem{Review}
	Timo J. T. Koski, John M. Noble
	\emph{A Review of Bayesian Networks and Structure Learning}

\end{thebibliography}

\end{document}


\selectlanguage{english}
\begin{abstract}
    \noindent For the first project of the Computer Simulations (ELTE Physics MSc) course I propose a concept of an N-body simulation, which aims to reproduce the satellite formation inside asteroid belts around a larger stellar object (eg. a gas giant or a star). Due to the N-body simulations' high computational difficulty, my spare objective is to observe at least some form of clustering process inside these type of systems. To achieve these goals, I will use Newton's law of universal gravitation, solving the particles' equation of motion by a simple 4th order Runge-Kutta function. Other numerical methods - described in Sec. III. will be optionally tested.
\end{abstract}

\begin{multicols}{2}
\section{Introduction}
The problem of gravitational- or electromagnetic attraction of more, than 2 bodies are impossible to solve analitically, except for some finite special cases. To study the motion of the particles in such systems we're ought to rely on numerical simulations and approximations. The computational difficulty of the problem grows non-linearly as we try to simulate more and more particles, and thus these simulations are required to be reinforced by some clever numerical tricks to overcome the barrier of immense computational times. \par
In this project I tried to create a gravitational n-body simulation, which could be used to simulate the motion of relatively small, but still interesting amount of bodies. As I've achieved pretty good values for runtime, it was still too slow, to simulate a system with eg. 1000 bodies on my personal computer for hundreds of years. In this paper I present my current results at the deadline.

\section{Theoretical background}
In the short description I've already covered some of the theoretical background of the gravitational n-body problem. I've already wrote, that the force, acting on the $i$th body could be described by the following sum:

\begin{equation} \label{eq:1}
m_{i} \boldsymbol{\ddot{r}}_{i}
=
- G \sum_{i \neq j} \frac{m_{i} m_{j}}{\left| r_{i} - r_{j} \right|^{2}} \frac{\boldsymbol{r}_{i} - \boldsymbol{r}_{j}}{\left| r_{i} - r_{j} \right|}
\end{equation}
Using this, one can simply describe the acceleration acting on the $i$th body:

\begin{equation} \label{eq:2}
\boldsymbol{\ddot{r}}_{i}
=
- G \sum_{i \neq j} \frac{m_{j}}{\left| r_{i} - r_{j} \right|^{2}} \frac{\boldsymbol{r}_{i} - \boldsymbol{r}_{j}}{\left| r_{i} - r_{j} \right|}
\end{equation}
Which differential equation essentially should be solved numerically for the $x$, $y$ and $z$ components of the $\boldsymbol{r}$ vector to acquire the coordinates and velocities of the individual particles. \par
In 3D coordinates it is an article-level problem to study the possible 3D trajectories \citep{3Dtrajectory} and the system could be seriously unstable. After acknowledging these facts, I decided to study the behavior of the setup, where the objects are scattered in a 2D plane around a central object. In my simulations the central object was the Jupiter, and the objects around it symbolized the asteroid belt.

\section{Preliminary setup of the simulation}
To unambiguously define the initial setup of the system, I decided to create an asteroid-generation pipeline, following the same steps in order in the generation of every new objects. \par
At the I. step the size and mass of the central object where chosen, along with number of small bodies as well. \par
At the II. step the pipeline generated spherical bodies with various sizes, but constant densities. The masses were calculated next from these two values. Here, only the minimal and maximal radius of the small bodies were given to the pipeline. For the densities I've chosen $\rho_{S} = 2270\ \text{kg}/\text{m}^{3}$ consistently, which is a relatively medium-size value for asteroids \citep{krasinsky2002hidden}. \par
At the III. step the initial coordinates and velocities of the small bodies were generated. According to Kepler's first law, a satellite orbits a central object on an elliptic orbit, where the central object is situated in one of the focal points. When the object is gravitationally bound, its orbit's shape is an ellipse or in special case, a circle. The distance of the satellite from the central body could be easily expressed:

\begin{equation} \label{eq:3}
d
=
\frac{r_{p}}{1 + e * \cos{\varphi}}
\end{equation}
where $r_{p}$ is the length of the perigee, $e$ is the eccentricity, $\varphi$ is the polar angle. Here, I generated random $r_{p}$ perigee distances and $e$ eccentricities from a pre-defined interval. The possible perigee distances' values were $r_{p} = 10 R \pm 1.5 R$, where $R$ is the radius of the central planet, while the maximal eccentricity was chosen to be $e_{max} = 0.4$. Using this two values, the semi-major ($a$) and semi-minor ($b$) axis of the trajectories for every body could be calculated, as follows:

\begin{equation} \label{eq:4}
a = \frac{r_{p}}{1 - e^2}
\end{equation}
\begin{equation} \label{eq:5}
b = \frac{r_{p}}{\sqrt{1 - e^2}}
\end{equation}
After this, I generated a random $\varphi$ azimuth angle and calculated the coordinates, using the following forms:

\begin{equation} \label{eq:6}
\begin{pmatrix}
x \\
y
\end{pmatrix}
=
\begin{pmatrix}
a * \cos{\varphi} \\
b * \sin{\varphi}
\end{pmatrix}
\end{equation}
Using the Vis-Viva equation the length of the velocity vector $\left| \boldsymbol{v} \right|$ could be calculated, if the initial setup for every small body is considered as a two-body problem of the asteroid and the central object. Since the masses of the small bodies are very small, compared the to central object, it is a perfectly fine to use this approximation.

\begin{equation} \label{eq:7}
\left| \boldsymbol{v} \right|
=
\sqrt{GM \left( \frac{2}{a} - \frac{1}{d} \right)}
\end{equation}
where $G$ is the gravitational constant, $M$ is the mass of the central object, $a$ is the semi-major axis of the currently described small body, $d$ is the distance of this body from the central object's center of mass. We also know, that the velocity vector always a tangent of the satellites trajectory in every point. It could be calculated by taking the gradient of the ellipse's coordinates:

\begin{equation} \label{eq:8}
\boldsymbol{e}_{t}
=
\frac{\boldsymbol{\nabla} \boldsymbol{r}}{\left| \boldsymbol{\nabla} \boldsymbol{r} \right|}
=
\frac{1}{\left| \boldsymbol{\nabla} \boldsymbol{r} \right|}
\boldsymbol{\nabla}
\begin{pmatrix}
x \\
y
\end{pmatrix}
=
\frac{1}{\left| \boldsymbol{\nabla} \boldsymbol{r} \right|}
\boldsymbol{\nabla}
\begin{pmatrix}
a * \cos{\varphi} \\
b * \sin{\varphi}
\end{pmatrix}
\end{equation}
\begin{equation} \label{eq:9}
\boldsymbol{e}_{t}
=
\frac{1}{\left| \boldsymbol{\nabla} \boldsymbol{r} \right|}
\begin{pmatrix}
-a * \sin{\varphi} \\
b * \cos{\varphi}
\end{pmatrix}
\end{equation}
The actual velocity vector then could be written in the following form, using the result from the (\ref{eq:7}) equation:

\begin{equation} \label{eq:10}
\boldsymbol{v}_{t}
=
\frac{\left| \boldsymbol{v} \right|}{\left| \boldsymbol{\nabla} \boldsymbol{r} \right|}
\begin{pmatrix}
-a * \sin{\varphi} \\
b * \cos{\varphi}
\end{pmatrix}
\end{equation}
After acquiring the velocity vectors and coordinates, the (\ref{eq:2}) differential equation could be solved for every $i$th object numerically.

\section{Technical details}
Since I used Python (especially Jupyter Notebook) for my simulation, it was crucial to speed up the process, since Python is not the fastest programming language regarding runtime. I used two different methods to achieve a speed-up. First, the simulation only calculated the $j$th force acting on the $i$th object, if the asteroids, indexed by $i$ and $j$ were closer, than $2R$ to each other. Second, I used the \texttt{numba} library's \texttt{@jit(nopython=True)} decorator to greatly optimize my code. This decorator compiles the Python functions into machine code before running them, thus greatly enhancing the runtime. Sadly it has strict limitations, so I was forced to write my code accordingly. \par
The full source code, used files and everything related to the project could be found in my GitHub repository of this course\footnote{\url{https://github.com/masterdesky/ELTE\_Comp\_Simulations\_2020}}.

\section{Solving the differential equations}
To solve the equation of motions numerically for all bodies, I used a simple (not adaptive) fourth-order Runge-Kutta function. The functionality of this iterative algorithm is well-known and is the following:

\begin{equation}
k_{1} = dt * \dot{y}_{n}
\end{equation}
\begin{equation}
k_{2} = dt * \left( \dot{y}_{n} + 0.5 * k_1 \right)
\end{equation}
\begin{equation}
k_{3} = dt * \left( \dot{y}_{n} + 0.5 * k_2 \right)
\end{equation}
\begin{equation}
k_{4} = dt * \left( \dot{y}_{n} + k_3 \right)
\end{equation}
\begin{equation}
dy = \frac{k_{1} + 2 * k_{2} + 2 * k_{3} + k_{4}}{6}
\end{equation}
\begin{equation}
y_{n+1} = y_{n} + dy
\end{equation}
In the simulation the $\dot{y}_{n}$ represented the $\dot{r}$ and $\ddot{r}$ values as well, which were incremented by parallel.

\section{Results and problems}
The results were quite disappointing, and I didn't have enough time to fix the trivial, but crucial problem with my simulation. The whole code works very well, at least it doesn't have any logical or physical flaws. The main problem was, that immediately from the beginning, the orbiting bodies' kinetic energy started to grow, which is quite a surprise for an RK4 algorithm, as it is much more common phenomenon, when using the simple Euler's method. \par
After many unsuccessful fixing attempt, - at first glance - I finally solved the problem by choosing the time-step to a smaller value. By trial and error I found, that with $dt \leq 0.001$ years, the simulation becomes highly unstable. Maybe this could be still an acceptable and working parameter, if I'd change RK4 to some higher-order Runge-Kutta function, but I've had very limited time, as I've mentioned it already. Sadly, RK4 still didn't reserved kinetic energy for longer time periods, and started to slightly, but continuously grow. The effect caused by choosing different time steps could be objectively observed by starting the simulation from the same initial conditions with different $dt$ values and let it run for some time.

\begin{center}
    \includegraphics[width=0.5\textwidth]{{img_src/kin_E_max_10_y_dt_0.001_y}.pdf}
    \captionof{figure}{Kinetic energy changes of an arbitrary satellite with time step $dt=0.001$ for $10$ simulated years. A slight grow of the curve could be observed. The local extremas are marked by red and oranges 'X' markers.} \label{fig:1}
\end{center}
Using the time step $dt=0.001$ for $10$ simulated years, the final arrangement of the simulated asteroids could be seen on figure (\ref{fig:4}) and figure (\ref{fig:5}). Running the simulation even further, the energy growth of the small objects in the simulated asteroid belt simply blew up the simulation, as they started to move exponentially faster every iteration after some time.
\begin{center}
    \includegraphics[width=0.5\textwidth]{{img_src/kin_E_max_100_y_dt_0.001_y}.pdf}
    \captionof{figure}{Kinetic energy changes of an arbitrary satellite with time step $dt=0.001$ for $100$ simulated years. A slight grow of the curve could be observed early, then an exponential upstream blows up the simulation. The local extrema are marked by red and oranges 'X' markers. The growth could be seen best by observing the slope of the red line.} \label{fig:2}
\end{center}
In contrast, choosing the step size parameter as $dt = 0.0001$, the energy seemed to remain conserved and the simulation remained totally stable.
\begin{center}
    \includegraphics[width=0.5\textwidth]{{img_src/kin_E_max_100_y_dt_0.0001_y}.pdf}
    \captionof{figure}{Kinetic energy changes of an arbitrary satellite with time step $dt=0.0001$ for $100$ simulated years. There are no relevant energy growth could be seen. The local extrema are marked by red and oranges 'X' markers.} \label{fig:3}
\end{center}
The final positions and velocities of the small bodies, running the simulation with these parameters could be seen on Fig. (\ref{fig:6}) and Fig. (\ref{fig:7}). It seems a wise choice to run the simulation with $dt=0.0001$ and let it run for a long time. However it would still not yield any useful results regarding the moon formation or clustering of bodies in an asteroid belt. The total runtime for $100$ years with this time step was $5.25$ hours, but we should simulate at least a few million years to get any kind of results. The simulation maybe could be made "faster", if we would simulate a system, where the asteroids orbit a gas giant, which also orbits a star, thus creating Lagrangian points, where the small bodies could accumulate easier.

\section{Discussion}
At least, I've successfully built a gravitational n-body problem simulation, which could handle time steps relatively fast. Since I couldn't let the simulation run for longer time, and with smaller time steps, I couldn't detect any kind of gravitational clustering, or Moon-formation in an asteroid belt. However I proposed some ideas, which could be further examined in the future. \par
I've also made some animations of the working simulation, which could be reached on my YouTube channel\footnote{\url{https://www.youtube.com/channel/UCBDSB7PdQ3E9l9WSBsTy7cQ}}, under the "Planetary Motions" playlist.

\end{multicols}


\chapter{Hypothesis Testing and Model Selection}
Hypothesis testing (also known as model selection, particularly when it is
done using the method in Section~\ref{sec:marginal_likelihood})
is a very important topic that is traditionally considered
a different topic from parameter estimation. However, in Bayesian statistics
we will see that hypothesis testing is basically the same thing as parameter
estimation! The one difference, for us, will be that we will sometimes change
the prior distribution a little bit.

One big advantage of Bayesian statistics is that it {\it unifies}
parameter estimation and hypothesis
testing\footnote{``Unifies'' is a popular word for physicists. It means that
two seemingly different topics are fundamentally the same, or at least closely
related.}. That's good news, because instead of having to
understand two different topics, we only have to understand one!

To see why hypothesis testing is fundamentally the same as parameter estimation,
you only need to
understand how parameter estimation works from a Bayesian point of view, which
we have already studied.
Parameter estimation is nothing more than testing a bunch of hypotheses about
the value of the parameter. For example, $\theta=1$ vs. $\theta=2$ vs. $\theta=3$ and
so on. If we have their posterior probabilities, then we've tested them.

\section{An Example Hypothesis Test}
Suppose we were performing a Bayesian parameter estimation analysis using a
Bayes' Box. Here is an example Bayes' Box with made up numbers:

\begin{table}[!ht]
\begin{center}
\begin{tabular}{|c|c|c|c|c|}
\hline
\tt{possible values} & \tt{prior} & \tt{likelihood} & \tt{prior} $\times$ \tt{likelihood} & \tt{posterior}\\
$\theta$ & $p(\theta)$ & $p(x|\theta)$ & $p(\theta)p(x|\theta)$ & $p(\theta|x)$\\
\hline
1.5 & 0.25 & 0.2 & 0.05 & 0.1\\
2.0 & 0.25 & 0.4 & 0.1 & 0.2\\
2.5 & 0.25 & 0.6 & 0.15 & 0.3\\
3.0 & 0.25 & 0.8 & 0.2 & 0.4\\
\hline
Totals & 1 & & 0.5 & 1\\
\hline
\end{tabular}
\end{center}
\end{table}
Suppose we wanted to test the following two hypotheses about the parameter $\theta$.
The first hypothesis $H_0$ is a ``null hypothesis'', and the second hypothesis,
$H_1$, is an ``alternative hypothesis''.
\begin{eqnarray}
H_0: && \theta = 2\\
H_1: && \theta \neq 2
\end{eqnarray}
In classical statistics, if you saw a question phrased in this way, you would
need to come up with a {\it test statistic}
and then calculate a {\it p-value}, which tries to say something about whether
the value of the test statistic would be considered extreme, under the
assumption that $H_0$ is true.
In Bayesian statistics, the only thing we need to do is calculate
the posterior probability of $H_0$ and the posterior probability of $H_1$.
The posterior probability of $H_0$ is given by:
\begin{eqnarray}
P(H_0|x) &=& P(\theta = 2|x)\\
&=& 0.2
\end{eqnarray}
All we did here was look up the appropriate number in the Bayes' Box! The
posterior probability of $H_1$ is only slightly harder (but still easy)
to calculate: $H_1$ will
be true if $\theta$ takes any value other than 2. Therefore, the posterior
probability of $H_1$ is
\begin{eqnarray}
P(H_1|x) &=& P(\theta = 1.5 \vee \theta = 2.5 \vee \theta = 3|x)\\
&=& P(\theta = 1.5|x) + P(\theta = 2.5|x) + P(\theta = 3|x)\\
&=& 0.1 + 0.3 + 0.4\\
&=& 0.8.
\end{eqnarray}
Here we used the fact that everything in a Bayes' Box is mutually exclusive
(only one of the hypotheses is true) so we could add the probabilities.
Alternatively, you could have just noticed that $H_1$ is true if $H_0$ is false.
So $P(H_0|x) + P(H_1|x) = 1$, which implies $P(H_1|x) = 1 - P(H_0|x)$.

\section{The ``Testing'' Prior}
Here we will study a hypothesis testing example that involves a null and an
alternative hypothesis. Since the bus example has been used a lot, we will now
switch over to a different example.

Suppose it is known that the mean systolic blood pressure
in the general population is 120 mm Hg, with a standard deviation of
15 mm Hg (millimetres of mercury is an
old fashioned unit for pressure, even though it sounds like a unit of length).
A new drug is developed that may
be helpful in reducing blood pressure. A sample of $N=100$ people
(who can be considered representative of the general population)
are given the drug, and their systolic blood pressure is measured. This results
in 100 blood pressure measurements $\{x_1, x_2, ..., x_N\}$, which will be
our data. As a shorthand, I'll sometimes write $\boldsymbol{x}$
(a bold vector) to denote the data collectively,
instead of $\{x_1, x_2, ..., x_N\}$.

We are interested in whether the drug works. Let $\mu$ be the mean systolic
blood pressure
that would apply in the general population if everyone was taking the
drug. Our goal is to infer the value of $\mu$ from the data. In classical
statistics, this is sometimes phrased as a hypothesis test between the two
competing hypotheses. We will not be concerned with the possibility that the
drug has the opposite effect to what is intended.
\begin{equation}
\begin{array}{ll}
H_0: & \mu = 120 \textnormal{ (the drug does nothing)}\\
H_1: & \mu < 120 \textnormal{ (the drug reduces blood pressure)}
\end{array}
\end{equation}
Suppose the mean of all the data values was
\begin{eqnarray}
\bar{x} &=& \frac{1}{N} \sum_{i=1}^{100} x_i\\
&=& 115.9.
\end{eqnarray} % and (x squared)bar = 13654.82
Does this data provide evidence against $H_0$ and in favour of $H_1$? In
classical statistics this question would be addressed using a {\it p-value}.
The p-value would be the probability of getting a result this extreme or
a result more extreme than what is observed, assuming that the ``null hypothesis''
is true. That is,
\begin{eqnarray}
\textnormal{p-value} = P(\bar{x} \leq 115.9 | H_0).
\end{eqnarray}
In case you're curious, the p-value in this case is 0.0031, which is usually
taken to mean that there is fairly strong evidence against $H_0$ and in favour
of $H_1$. To calculate the p-value I had to assume that the probability distribution
for the data values $\{x_1, x_2, ..., x_{100}\}$ was a normal distribution
with a known standard deviation of $\sigma=15$, and
that they were independent:
\begin{eqnarray}
x_i \sim \mathcal{N}(\mu, \sigma^2). \label{eq:normal}
\end{eqnarray}

In Bayesian statistics, p-values are not used. Instead, we should think of this
as a parameter estimation problem. We can state a set of hypotheses about the
value of $\mu$, and then choose a prior distribution, update to a posterior
distribution, etc. Then our result will be the posterior probability of the
null hypothesis, $P(H_0 | \boldsymbol{x}) = P(\mu = 120 | \boldsymbol{x})$.
This is helpful because the posterior probability of the null hypothesis is
exactly what we want. It is a description of how plausible the null hypothesis
is given the data. It is not some other probability that isn't really relevant.
We can also get the posterior probability of $H_1$ by summing the posterior
probabilities for all other values of $\mu$ apart from 120, or by using
$P(H_1 | \boldsymbol{x}) = 1 - P(H_0 | \boldsymbol{x})$.

There is only one minor tweak we need to make to make Bayesian inference an
appropriate framework for solving this problem. When the null and alternative
hypotheses are written like we wrote them above, it implies that the value of $\mu$
that we are calling the ``null hypothesis'' is a {\it special value that is
especially plausible}. To take this into account in our Bayesian analysis we
need to make sure the prior distribution recognises there is a special
value of the parameter that we think is extra plausible. When we do this, we
will call it a {\it testing prior}. An example of a testing prior and the
resulting Bayes' Box for
the blood pressure problem is given in Table~\ref{tab:testing_prior}.
The R code for calculating these results is given below.

\begin{minted}[mathescape,
               numbersep=5pt,
               gobble=0,
               frame=single,
               framesep=2mm, fontsize=\small]{r}
# Parameter values
mu = seq(110, 120)

# Make the testing prior
prior = rep(0.5/10, 11)
prior[11] = 0.5

# Compute the likelihood for the 100 data points.
# The numbers get close to 0, so let's use logs
log_lik = rep(0, 11)

# Use a for loop to loop over all data values
# and multiply the likelihoods
for(i in 1:100)
{
  log_lik = log_lik + dnorm(x[i], mean=mu, sd=15, log=TRUE)
}

# Rescale the likelihood for readability
lik = exp(log_lik - max(log_lik))*1000
#lik = lik/max(lik)*1000

# Calculate the posterior
h = prior*lik
post = h/sum(h)

# The null hypothesis
post[11]
\end{minted}

\begin{table}[!ht]
\begin{center}
\begin{tabular}{|c|c|c|c|c|}
\hline
\tt{possible values} & \tt{prior} & \tt{likelihood} & \tt{prior} $\times$ \tt{likelihood} & \tt{posterior}\\
$\mu$ & $p(\mu)$ & $p(\boldsymbol{x}|\mu)$ & $p(\mu)p(\boldsymbol{x}|\mu)$ & $p(\mu|\boldsymbol{x})$\\
\hline
110 & 0.05 & 0.44	& 0.02 & 0.0001\\
111 & 0.05 & 4.83	& 0.24 & 0.0012\\
112 & 0.05 & 34.12	& 1.71 & 0.0086\\
113 & 0.05 & 154.64	& 7.73 & 0.0389\\
114 & 0.05 & 449.33	& 22.47 & 0.1129\\
115 & 0.05 & 837.13	& 41.86 & 0.2103\\
116 & 0.05 & 1000.00    & 50.00 & 0.2512\\
117 & 0.05 & 756.93	& 38.30 & 0.1924\\
118 & 0.05 & 376.15	& 18.81 & 0.0945\\
119 & 0.05 & 118.44	& 5.92 & 0.0298\\
{\bf 120} & {\bf 0.5}   & {\bf 23.91} & {\bf 11.96} & {\bf 0.0601}\\
\hline
Totals & 1 & & 199.01 & 1\\
\hline
\end{tabular}
\caption{\it An example of a testing prior for the blood pressure problem. We
give more prior probability to the special value $\mu=120$ because it is
particularly plausible. For readability I have rescaled the likelihoods so that
the maximum is 1000. Note that the posterior probability of $H_0$ can simply
be read off the table.
\label{tab:testing_prior}}
\end{center}
\end{table}

The conclusion of our Bayesian hypothesis test is that the posterior probability
of $H_0$ is 0.0601. Recall that the classical p-value was 0.0031. These numbers
are very different, and {\it there is no reason why they should be similar}. The
p-value might imply that the evidence is overwhelming (if you are not experienced
at interpreting p-values), but the posterior probability still says there's a
6\% chance the drug does nothing.

Note that the calculation of the posterior distribution uses {\it all} of the
data values, rather than reducing the whole data set down to a single number
(the sample mean $\bar{x}$). In this particular example, reducing the whole
dataset to a single number is harmless\footnote{In this problem, the sample mean
is a ``sufficient statistic'': deleting all of the data and using just the
mean has no consequences!}. But in different situations (e.g. if your sampling distribution
or likelihood was based on the heavy-tailed Cauchy distribution instead of a normal
distribution), reducing an entire data set to a single ``test statistic'' can
be extremely wasteful!

Note also that there were some fairly arbitrary decisions made in choosing our
testing prior. We decided not to allow $\mu > 120$, but the analysis could
also have allowed for that. The discrete approximation was fairly coarse. Finally, we
assumed $\mu$ couldn't be lower than 110, and had a uniform prior for all
$\mu$ values apart from 120. Some of these assumptions can and should be
questioned when applying Bayesian hypothesis testing in practice.
In Figure~\ref{fig:testing_priors}, there are three possible ideas for what
the prior should be in the blood pressure question. They may all seem somewhat
reasonable in this situation, but could lead to different conclusions.

Prior 1 is basically the same as the prior in our Bayes' Box, although it goes
down to $\mu=100$ and divides the possible $\mu$ values more finely. This prior
says the null has a 50\% probability, and if $\mu$ is not equal to 120, then it
could be anything.
Prior 2
is similar, but has only 30\% of the prior probability on the null hypothesis,
instead of 50\%,
and the shape of the prior is non-uniform for the lower values of $\mu$.
This is like saying ``$\mu$ could be precisely 120, and if it's not precisely
120, then it is probably at least {\it close} to 120''. In a lot of hypothesis
testing situations this would be a more accurate description of our prior
beliefs than Prior 1.
Prior 3 isn't really a testing prior at all (it doesn't have a spike), but is
just a bell-shaped prior. This is like saying ``Alright, I would never believe
$\mu$ is {\it exactly} 120, but I think there's a reasonable chance it's {\it
close} to 120. Often, it would be nonsense to think the null hypothesis
is perfectly true, to an arbitrary level of accuracy. Something like Prior 3
would be more appropriate.
These three priors would all give different results, and the appropriate choice
depends on the individual problem you are solving.

\begin{framed}
{\bf Remember, if the conclusions depend sensitively on the choice of the
prior distribution, that is an important finding. You either need to be
really careful about choosing your prior, or you need more data.}
\end{framed}

\begin{figure}[!ht]
\begin{center}
\includegraphics[scale=0.6]{Figures/testing_priors.pdf}
\caption{\it Three possible priors we could use for the blood pressure question.
All may seem ``reasonable'', and the choice can affect the results (quite
significantly in some cases). Care should be taken when choosing the prior
in hypothesis testing problems.
\label{fig:testing_priors}}
\end{center}
\end{figure}

\section{Some Terminology}
There is some alternative terminology that is widely used and is particularly
popular in Bayesian hypothesis testing (aka model selection) problems. Suppose
there were two hypotheses $H_1$ and $H_2$, and some data $x$. Now, $H_1$ and
$H_2$ might be a null and alternative hypothesis, or they might be two
particular values of the parameter, or something else. Two repetitions of Bayes' rule
for these two hypotheses are:
\begin{eqnarray}
P(H_1 | x) &=& \frac{P(H_1)p(x|H_1)}{p(x)}\\
P(H_2 | x) &=& \frac{P(H_2)p(x|H_2)}{p(x)}
\end{eqnarray}
These could also be written in words:
\begin{eqnarray}
\textnormal{posterior} &=& \frac{\textnormal{prior}\times\textnormal{likelihood}}{\textnormal{marginal likelihood}}
\end{eqnarray}

Dividing these two equations gives the {\it odds form} of Bayes' rule, which
deals with ratios of probabilities instead of probabilities themselves.
\begin{eqnarray}
\frac{P(H_1 | x)}{P(H_2|x)} &=& \frac{P(H_1)}{P(H_2)} \times
\frac{p(x|H_1)}{p(x|H_2)}\label{eq:odds_form}
\end{eqnarray}
In words, this can be written as:
\begin{eqnarray}
\textnormal{posterior odds} = \textnormal{prior odds}
\times
\textnormal{bayes factor}
\end{eqnarray}
Sometimes people talk about odds (or odds ratios, which are the same thing)
and Bayes Factors instead of about prior and
posterior probabilities. The odds tell us how plausible $H_1$ is compared to
$H_2$. For example, a posterior odds ratio of 5 means $H_1$ is 5 times as plausible
as $H_2$. Of course, odds can be greater than 1 even though probabilities
cannot be. The Bayes Factor is the ratio of the likelihoods. Results are often
quoted as Bayes Factors because that's the part of the equation where the
data is important. If you say ``The Bayes Factor for $H_1$ over $H_2$ was 10'',
then whoever you're talking to is free to apply whatever prior odds they like,
whereas if you state the posterior odds then people may wonder what your prior
odds were.

\section{Hypothesis Testing and the Marginal Likelihood}\label{sec:marginal_likelihood}
The Bayes' factor in Equation~\ref{eq:odds_form} is the ratio of likelihoods
for two hypotheses $H_1$ and $H_2$. If we wanted to calculate the Bayes Factor
for $H_0$ and $H_1$ in the blood pressure example, we could easily get the likelihood
for $H_0$ (it's right there in the Bayes' Box). But how would we get $p(x|H_1)$,
which needs to be a single number? $H_1$ is the statement $\mu = 100$ {\bf or}
$\mu = 111$ {\bf or} $\mu = 112$ and so on up to $\mu = 119$.

Imagine we had left $\mu=120$ out of our Bayes' Box and just done parameter
estimation within the context of $H_1$ (i.e. assuming, for argument's sake,
that $H_1$ is true). This would involve a {\it reduced} Bayes' Box with one
less row in it. We would end up getting some marginal likelihood
$p(x) = \sum p(\theta)p(x|\theta)$.
The key is to realise that since we are assuming $H_1$ throughout, the
marginal likelihood is really $p(x|H_1) = \sum p(\theta|H_1)p(x|\theta, H_1)$,
which is exactly the thing we need to calculate the Bayes Factor!

All of this implies
there are two mathematically equivalent ways of doing Bayesian hypothesis testing,
or model selection. One is to make a big model that includes both the null and
the alternative hypothesis. The Bayes' Box with a testing prior accomplishes this.
In most cases this is the most convenient way to do the calculations.

The other way is to do the two analyses separately. First, do parameter estimation
within the context of $H_1$. Then, do parameter estimation within the context
of $H_2$. Then, use the marginal likelihoods as if they were likelihoods, to
compare $H_1$ vs. $H_2$. This second way of calculating Bayes Factors is
most useful when the two analyses were actually done separately by different
people.

%\section{Analytic Solution}
%In this section we'll solve the blood pressure model selection problem
%analytically. Along the way, we'll learn a useful conjugate prior for when the
%likelihood is based on a normal distribution.

%Firstly, let's write down the likelihood,
%which is a product of $N$ univariate normal densities with mean $\mu$ and
%standard deviation $\sigma$:
%\begin{eqnarray}
%p(\boldsymbol{x} | \mu) &=&
%\prod_{i=1}^N \frac{1}{\sigma\sqrt{2\pi}}
%\exp
%\left[-\frac{1}{2\sigma^2}\left(x_i - \mu\right)^2\right].
%\end{eqnarray}
%We can rearrange this a bit, which will be useful later:
%\begin{eqnarray}
%p(\boldsymbol{x} | \mu) &=& \sigma^{-N}(2\pi)^{-N/2}
%\exp
%\left[-\frac{1}{2\sigma^2}\sum_{i=1}^N\left(x_i - \mu\right)^2\right]\\
%&=& \sigma^{-N}(2\pi)^{-N/2}
%\exp
%\left[-\frac{1}{2\sigma^2}\left(N\bar{x^2} - 2N\mu\bar{x} + N\mu^2\right)\right]\\
%&=& \sigma^{-N}(2\pi)^{-N/2}
%\exp
%\left[-\frac{N}{2\sigma^2}\left(\bar{x^2} + \mu^2\right) + \frac{N\mu}{\sigma^2}\bar{x}\right].\label{eq:lik_simplified}
%%\sum_{i=1}^N\left(x_i^2 - 2\mu x_i + \mu^2\right)\right].
%\end{eqnarray}
%where $\bar{x}$ is the arithmetic mean of the data and $\bar{x^2}$ is the mean
%squared value of the data. Notice that the likelihood only depends on the data
%through the values of $\bar{x}$ and $\bar{x^2}$. In fact, if we're only trying
%to infer $\mu$ and not $\sigma$ then the part that depends on $\bar{x^2}$
%can be treated as a ``constant'', and will not affect the posterior for $\mu$.
%This is why $\bar{x}$ is a sufficient statistic. If we were treating $\sigma$
%as unknown as well, $\bar{x}$ and $\bar{x^2}$ would be sufficient statistics.

%As we saw before, model selection problems can be solved in two different ways
%(but with equivalent results). We can calculate the posterior for $\mu$ in
%a way that includes both $H_0$ and $H_1$ in the calculation from the beginning
%(perhaps assigning 50\% prior probability to $H_0$), or we can compute the
%marginal likelihoods for $H_0$ and $H_1$ separately. In analytical calculations
%the separate calculation is the most popular method, so we'll use it here.

%The posterior odds ratio for $H_0$ over $H_1$ is
%\begin{eqnarray}
%\frac{P(H_0 | \boldsymbol{x})}{P(H_1|\boldsymbol{x})} &=& \frac{P(H_0)}{P(H_1)} \times
%\frac{p(\boldsymbol{x}|H_0)}{p(\boldsymbol{x}|H_1)}\label{eq:odds_form2}.
%\end{eqnarray}
%If we're assigning 50\% prior probability to $H_0$ and to $H_1$, then the
%prior odds ratio is $0.5 / 0.5 = 1$. Therefore we just need the two likelihoods,
%$p(\boldsymbol{x} | H_0)$ and $p(\boldsymbol{x} | H_1)$. The first of these is fairly straightforward to
%get, since $H_0$ implies $\mu = 120$. We just calculate the value of the
%likelihood using Equation~\ref{eq:lik_simplified}, which we've already done
%(it was in Table~\ref{tab:testing_prior}, albeit arbitrarily scaled). Its value
%is $p(\boldsymbol{x} | H_0) = 1.638 \times 10^{-159}$.

%To complete the calculation we need the value of $p(\boldsymbol{x}|H_1)$, but
%this is a bit more difficult since $H_1$ doesn't correspond to a particular
%value of $\mu$, but instead implies that $\mu$ is any value other than 120.
%So what exactly does it mean? In the discrete situation, it's possible to
%calculate $p(\boldsymbol{x}|H_1)$ by recognising that $H_1$ is equivalent to
%$(\mu = 110) \vee (\mu = 111) \vee... (\mu = 119)$. Then
%we can use the sum rule:
%\begin{eqnarray}
%p(\boldsymbol{x}|H_1) &=& \sum_{\mu=110}^{119} p(\mu | H_1)
%p(\boldsymbol{x}|\mu, H_1).\label{eq:discrete_evidence}
%\end{eqnarray}
%Since we're working analytically, we'll be replacing this marginal likelihood
%with a continuous version that allows any possible $\mu$ value on the real line.
%The integral for the marginal likelihood will take a form analogous to
%Equation~\ref{eq:discrete_evidence}:
%\begin{eqnarray}
%p(\boldsymbol{x}|H_1) &=& \int p(\mu | H_1)
%p(\boldsymbol{x}|\mu, H_1) \, d\mu.\label{eq:continuous_evidence}
%\end{eqnarray}
%The limits for the integration must be whatever range of $\mu$ is possible.
%The product of two terms inside the integral of Equation~\ref{eq:continuous:evidence} is the prior times the likelihood for a parameter estimation problem in
%which we want to infer $\mu$ from the data,

%Recall the notion of a ``conjugate prior'' which was discussed briefly earlier
%(when we used a beta prior together with a binomial sampling distribution).
%This is a mathematical trick where we choose a particular kind of prior
%that works together nicely with the mathematical form of the likelihood, so
%that we can do our calculations and actually get an answer in closed form.
%If we look at Equation~\ref{eq:lik_simplified} as a function of $\mu$, we
%can see that it is an exponential of a quadratic term, which has the same
%mathematical form as a gaussian.

%If we make the prior for $\mu$ (given $H_1$) a normal distribution, then the
%equation for the density will also be a gaussian function of $\mu$. Two
%gaussian functions multiplied together become a single gaussian function, whose
%integral we can do. This is the kind of thing that Bayesians used to have to
%do in order to make their calculations tractable. It's okay if you wouldn't
%have guessed that a normal distribution would be the conjugate prior here.

%A normal prior centered at centered at $m$ with a standard deviation of $s$
%has the following probability density function:
%\begin{eqnarray}
%p(\mu | H_1) &=& \frac{1}{s\sqrt{2\pi}}\exp
%\left[-\frac{1}{2s^2}\left(\mu - m\right)^2\right]
%\end{eqnarray}

%Substituting this and the likelihood into Equation~\ref{eq:continuous_evidence},
%and simplifying a bit, we get:
%\begin{equation}
%p(\boldsymbol{x}|H_1) = s^{-1}
%\sigma^{-N}(2\pi)^{-N/2-1} \int
%\exp
%\left[-\frac{1}{2s^2}\left(\mu - m\right)^2-\frac{N}{2\sigma^2}\left(\bar{x^2} + \mu^2\right) + \frac{N\mu}{\sigma^2}\bar{x}\right] \, d\mu.\label{eq:continuous_evidence2}
%\end{equation}

%To do the integral, we need to work with the term inside the exponential until
%it is of the form $-\frac{1}{2s'^2}(\mu - m')^2$, i.e. what's usually inside
%the exponential part of a gaussian function. If we could do that, then we
%could do the integral like so:
%\begin{equation}
%\int_{-\infty}^{\infty} \exp\left[C-\frac{1}{2s'^2}(\mu - m')^2\right]\, d\mu
%= s'\sqrt{2\pi}\exp(C)\label{eq:doable}
%\end{equation}
%which is just the normalisation condition of a normal distribution.
%Rearranging Equation~\ref{eq:continuous_evidence2} into this form is a pain
%(it involves expanding and simplifying various terms and then
%``completing the square''), and so I'll just state the result. If we set
%\begin{eqnarray}
%m' &=& \frac{\frac{m}{s^2} + \frac{N\bar{x}}{\sigma^2}}{\frac{1}{s^2} + \frac{N}{\sigma^2}}\\
%\frac{1}{s'^2} &=& \frac{1}{s^2} + \frac{N}{\sigma^2}\\
%C &=& \frac{m^2}{2s^2} + \frac{m'^2}{2s'^2}
%\end{eqnarray}
%then the integral in Equation~\ref{eq:continuous_evidence2} matches that in
%Equation~\ref{eq:doable}. Therefore the marginal likelihood is
%\begin{equation}
%p(\boldsymbol{x}|H_1) = \frac{s'}{s}
%\sigma^{-N}(2\pi)^{-N/2}
%\exp
%\left[\frac{m^2}{2s^2} + \frac{m'^2}{2s'^2}\right].
%\end{equation}


\documentclass[twoside]{MATH77}
\usepackage{multicol}
\usepackage[fleqn,reqno,centertags]{amsmath}
\begin{document}
\begmath 2.12 Finite Laguerre Series

\silentfootnote{$^\copyright$1997 Calif. Inst. of Technology, \thisyear \ Math \`a la Carte, Inc.}

\subsection{Purpose}

This subroutine computes the value of a finite sum of Laguerre polynomials,%
\begin{equation*}
y=\sum_{j=0}^{\text{N}}a_jL_j(x)
\end{equation*}
for a specified summation limit, N, argument, $x$, and sequence of
coefficients, $a_j$. The Laguerre polynomials are defined in
\cite{ams55:or-poly}.

\subsection{Usage}

\subsubsection{Program Prototype, Single Precision}

\begin{description}
\item[INTEGER]  \ {\bf N}

\item[REAL]  \ {\bf X, Y, A}(0:$m\geq $ N)
\end{description}

Assign values to X, N, and A(0), A(1), ..., A(N).
$$
\fbox{{\bf CALL SLASUM (X, N, A, Y)}}
$$
The sum will be stored in Y.

\subsubsection{Argument Definitions}

\begin{description}
\item[X]  \ [in] Argument of the polynomials.

\item[N]  \ [in] Highest degree of polynomials in sum.

\item[A()]  \ [in] The coefficients must be given in A(J), J = 0, ..., N.

\item[Y]  \ [out] Computed value of the sum.
\end{description}

\subsubsection{Modifications for Double Precision}

For double precision usage, change the REAL statement to DOUBLE PRECISION
and change the subroutine name from SLASUM to DLASUM.

\subsection{Examples and Remarks}

See DRSLASUM and ODSLASUM for an example of the usage of SLASUM. DRSLASUM
evaluates the following identity, the coefficients of which were obtained
from Table~22.10, page~799, of \cite{ams55:or-poly}.
\begin{equation*}
z=y-w=0,
\end{equation*}
where
\begin{multline*}
y = 7.2L_0(x)-3.2L_1(x)+108L_2(x)-144L_3(x)\\
+108L_4(x)-43.2L_5(x)+7.2L_6(x),
\end{multline*}
and
\begin{equation*}
w=0.01x^6.
\end{equation*}

\subsection{Functional Description}

The sum is evaluated by the following algorithm:%
\begin{gather*}
\hspace{-10pt}b_{N+2}=0,\quad b_{N+1}=0, \\
\hspace{-10pt}b_k=\frac{2k+1-x}{k+1}b_{k+1}-\frac{k+1}{k+2}b_{k+2}+a_k,
\quad k=\text{N},...,0,\\
\hspace{-10pt}y=b_0.
\end{gather*}
For an error analysis applying to this algorithm see \cite{Ng:1968:DSS} and
\cite{Ng:1971:RAC}. The first four Laguerre polynomials are
\begin{gather*}
L_0(x)=1,\quad L_1(x)=1-x,\\
L_2(x)=1-2x+0.5x^2,\\
L_3(x)=1-3x+1.5x^2-(1/6)x^3.
\end{gather*}
For $k \geq 2$ the Laguerre polynomials satisfy the recurrence
\begin{equation*}
kL_k(x)=(2k-1-x)L_{k-1}(x)-(k-1)L_{k-2}(x).
\end{equation*}
The Laguerre polynomials are orthogonal relative to integration with the
weight function $e^{-x}$ over the interval [0, $\infty )$, thus%
\begin{equation*}
\int_0^\infty e^{-x}L_i(x)L_j(x)\,dx=0\quad \text{if }i\neq j.
\end{equation*}
Laguerre polynomials are normally used only with an argument $x$ satisfying $%
x \geq 0.$

\bibliography{math77}
\bibliographystyle{math77}

\subsection{Error procedures and Restrictions}

The subroutine will return Y = 0 if N $< 0$. It is recommended that X
satisfy X $\geq 0.$

\subsection{Supporting Information}

The source language is ANSI Fortran~77.

\begin{tabular}{@{\bf}l@{\hspace{5pt}}l}
\bf Entry & \hspace{.2in} {\bf Required Files}\vspace{2pt} \\
DLASUM & \hspace{.35in} DLASUM\rule[-5pt]{0pt}{8pt}\\
SLASUM & \hspace{.35in} SLASUM\\
\end{tabular}

Based on a 1974 program by E.W. Ng, JPL. Present version by C.L. Lawson and
S. Y. Chiu, JPL, 1983.

\begcodenp

\lstset{language=[77]Fortran,showstringspaces=false}
\lstset{xleftmargin=.8in}

\centerline{\bf \large DRSLASUM}\vspace{10pt}
\lstinputlisting{\codeloc{slasum}}

\vspace{30pt}\centerline{\bf \large ODSLASUM}\vspace{10pt}
\lstset{language={}}
\lstinputlisting{\outputloc{slasum}}

\end{document}