Kepler-adapted symplectic N-body code SyMBA with modifications to include effects of pebble accretion, gas-envelope accretion,  eccentricity,inclination damping and planet migration is used for studying planet formation via pebble accretion. The modification in the integration step in SyMBA is -
\begin{equation}
 P^{\frac{\tau}{2}}M^{\frac{\tau}{2}}I^{\frac{\tau}{2}}D^{\tau}I^{\frac{\tau}{2}}M^{\frac{\tau}{2}}P^{\frac{\tau}{2}}
\end{equation}

\noindent
where $\tau$ is the time step, $D$ advances the planets along their osculating Kepler orbits,$I$ handles the secular interactions between the planets ,$M$ generates radial migration and eccentricity and inclination damping, and $P$ is associated with the accretion of pebbles and gas.
\noindent
Two additional adjustments  are made to the SyMBA algorithm : $(i)$ smoother partition function to decompose the gravitational force between two planets into forces that are non-zero, and $(ii)$ relation to compute planetary radii so that the system is approximately symplectic.

\subsubsection{Disc model}
The steady accretion rate of the disc gas onto the central star is given by
\begin{equation}
\Dot{M_*} = 3\pi\Sigma_g\nu = 3\pi\alpha\Sigma_gh_g^{2}\Omega
\end{equation}

\noindent
where $\Sigma_g$ is the gas surface mass density, $h_g$ is the pressure-scale height of a gas disc,$\Omega$ is the orbital frequency and $\alpha$ is the viscosity parameter which is constant throughout. Viscosity is given by $v=\alpha c_sh_g$ where $c_s$ is the isothermal sound speed.
The stellar mass accretion rate is given by
\begin{equation}
log(\frac{\Dot{M_*}}{M_\odot yr^-1})= -8-\frac{7}{5}log(\frac{t}{Myr} + 0.1)
\end{equation}

\noindent
The disc temperature is given by the heating source. In the inner region, viscous heating is predominant and in the outer region, stellar irradiation is predominant. The middle temperature is an approximate  of the viscous and irradiation temperatures.
All the parameters throughout the simulations are normalised.

\subsubsection{Pebble accretion rate}

Depending on whether the accretion is considered to be 2D or 3D, the mass growth rate for the embryos is given by
\begin{equation}
 \Dot{M_p} = min(\Dot{M_{2D}} ,\Dot{M_{3D}}) = min(\sqrt{\frac{8h_p}{\pi b}}, 1) \sqrt{\frac{\pi b^{2}}{2h_p}}\Sigma_p\Delta\nu
\end{equation}

\noindent
where ${h_p}$ is the pebble disc’s scale height, $b$ is the collisional cross-section radius of pebble flows,$\Sigma_p$ is the surface mass density of a pebble disc and $\Delta\nu$ is the relative speed between an embryo and a pebble.

\noindent
The transition from 2D to 3D occurs when $b \gg h_p$. The pebble mass flux decreases with time, as the stellar mass accretion rate $\Dot{M_{*g}}$ decreases and thus the disc’s density decreases. Efficiency of gas drag is measured by the Stoke's number $\tau_s$. Smaller the $\tau_s$, greater is the pebble mass accretion rate. It is found that $\tau_s \ll 1$ except in the inner regions of the disc. Therefore, the gas drag is efficient and the collisional cross-section for pebble accretion is large. This is the reason for the efficiency of pebble accretion process.

\subsubsection{Gas envelope accretion}
Gas accretion occurs only for larges masses and when accretion onto the core is low so that the gas can contract. The critical mass of the core above which gas accretion may occur is given by
\begin{equation}
 M_{pl,crit}\simeq 10(\frac{\Dot{M_{core}}}{10^{-6}M_Eyr^{-1}})^{\frac{1}{4}} M_E
\end{equation}

\noindent
where $\Dot{M_{core}}=\Dot{M_{p}}$.
The gas accretion rate does not depend on the opacity but is governed by how quickly the disc supplies gas to the planet. When the hill radius is two times the disc scale height, gas accretion stops.

\subsubsection{Planet migration}
The embryos and planets experience torque and tidal forces due to the gas discs. This results in radial migration and lowering of inclinations and eccentricities. Planets with a smaller mass experience type \textbf{I} migration and planets with larger masses undergo type \textbf{II} migration. The eccentricity and inclination damping and the planet migration is given by:

\begin{equation}
{a_e}= \frac{-\nu_r}{\tau_e}\hat{r} - \frac{0.5(\nu_\theta - \nu_\kappa}){\tau_e}\hat{\theta}
\end{equation}

\begin{equation}
{a_e}=\frac{2A_{cz}\nu_z+A_{sz}z\Omega}{\tau_i}\hat{k}
\end{equation}

\begin{equation}
{a_a}=\frac{\nu}{\tau_a}
\end{equation}

\noindent
For a planet with $M_E$, the torque is expected to become positive. When the planet becomes massive to open a gap in the disc, type \textbf{II} migration sets in. However, the transition from type \textbf{I} migration to type  \textbf{II} migration is unclear.

\subsubsection{Initial conditions}
A range of values for each parameter is taken in order to provide multiple environments for planet formation.
\begin{itemize}
\item The range of stellar metallicities used: [Fe/H] = (−0.5, 0.0, 0.5)
\item The initial disc age is varied over: $t_{init}$=(0.1,0.5,1.0)Myr.
\item The values for initial stellar mass rates are: $\Dot(M_{* g}$=(25.1,2.64,1.0) $M^\Theta$/ yr
\item The disc's viscosity parameter is changed over: $\alpha$ =  ($10^{-3},5x10^{-3},10^{-2}$)
\end{itemize}
One set of simulations is run without migration effects and another set is with the type 1 and 2 migration effects.
The seed embryos chosen roughly have the same mass of one lunar mass and they have a uniform radial distribution with distance between them approximately 70 hill radii.


% !TEX root = scombinatorics.tex
\documentclass[scombinatorics.tex]{subfiles}
\begin{document}

\chapter*{Notation}
\addcontentsline{toc}{chapter}{Preliminaries}

\label{minimax}

\def\medrel#1{\parbox[t]{6ex}{$\displaystyle\hfil #1$}}
\def\ceq#1#2#3{\parbox[t]{25ex}{$\displaystyle #1$}\medrel{#2}{$\displaystyle #3$}}

\thickmuskip=1mu plus 0.5mu minus 0.5mu
\medmuskip=0.5mu plus 0.2mu minus 0.2mu

Let $\U$ and $\V$ be two (large) sets.
Let $\phi(x\,;z)$ be a relation symbol, or a formula, whatever.
We denote by \emph{$\phi(\U\,;\V)$\/} the set $\{\<a,b\>\in\U\times\V\; :\; \phi(a\,;b)\}$ which we call: the relation defined by $\phi(x\,;z)$.
Sets of the form \emph{$\phi(\U\,;b)$}$=\{a\in\U\;:\; \phi(a\,;b)\}$, for some $b\in\V$, are called \emph{definable\/} sets.

In the first chapters we always restrict the study to the \emph{trace\/} of $\phi(\U\,;\V)$ on some finite set $A\times B$, where $A\subseteq\U$ and $B\subseteq\V$.
We wite $\phi(A\,;B)$ for $\phi(\U\,;\V)\cap A\times B$.
Similarly, we write $\phi(A\,;b)$ for the trace of $\phi(\U\,;b)$ on $A$, that is, the set $\phi(\U\,;b)\cap A$.
We call it a definable subset of $A$.

We denote by \emph{$\phi(\U\,;b)_{b\in\V}$} and \emph{$\phi(A\,;b)_{b\in\V}$} the collection of definable sets, respectively definable subsets of $A$.

A similar notations is used with the roles of $\U$ and $\V$ interchanged.
I.e., we think of $\U$ as the set of parameters defining subsets of $\V$.
We write \emph{$\phi(x\,;z)^{\rm op}$\/} to signal that the formula $\phi(x\,;z)$ is considered in this \emph{dual\/} setting.

For the model theoretic minded, it would be more appropriate to call the definable sets \textit{global types}, respectively \textit{types over $A$}.
But this would make the terminology (if possible) more obscure.

For $k\le|A|$ we use following notation interchangeably
\smallskip

\ceq{\hfill\emph{$\displaystyle{A\choose k}$}\medrel{=}\emph{$\vphantom{\Big[}A^{(k)}$}}
{=}
{\Big\{A'\subseteq A\ :\ |A'|=k \Big\}}
\smallskip

For $n$ a non negative integer we write

\ceq{\hfill \emph{$(n]$}}
{=}
{\{1,\dots,n\},}
\bigskip

\ceq{\hfill \emph{$n$}\medrel{=}\emph{$[n)$}}
{=}
{\{0,\dots,n-1\},}
\bigskip

\ceq{\rm and\hfill\emph{$[n]$}}
{=}
{\{0,\dots,n\}}\noindent\nolinebreak[4]\hfill\rlap{\textcolor{red}{\Large\danger}}
\bigskip

Note that the latter conflicts with the notation used in combinatorics.

\end{document}
%\noindent\llap{\textcolor{red}{\Large\danger}\kern1.5ex}


<% extends "base.tex" %>
<% block body %>
\begin{center}
\begin{tabular}{|c|c|}
  \hline
  \cellcolor[gray]{0.8}
  \begin{minipage}{5cm}
    \centering
    Classical Logic
  \end{minipage}
  &
  \cellcolor[gray]{0.8}
  \begin{minipage}{5cm}
    \centering
    Intuitionistic Logic
  \end{minipage}
  \\\hline

  {
    \huge
<%- if cl_result.is_provable() %>
    \cmark
    Provable
<%- else if cl_result.is_not_provable() %>
    \xmark
    Not provable
<%- else %>
    Unknown
<%- endif %>
  }
  &
  {
    \huge
<%- if int_result.is_provable() %>
    \cmark
    Provable
<%- else if int_result.is_not_provable() %>
    \xmark
    Not provable
<%- else %>
    Unknown
<%- endif %>
  }
  \\\hline
\end{tabular}
\end{center}

\section*{Input}

$<= prop %>$

<% match cl_result %>
<%- when SolverResult::Provable with (pf) %>
<%- match pf %>
<%- when Some with (pf) -%>
\section*{Proof (classical logic)}

The proposition is provable in classical logic. Below is one such proof diagram.

<% for fragment in pf %>
<%- if pf.len() > 1 %>
\subsection*{<= fragment.name %>}
<%- endif %>
\begin{prooftree}
<= fragment.source -%>
\end{prooftree}
<% endfor %>

<%- when None %>
<%- endmatch %>

<%- when SolverResult::NotProvable with (rft) %>
<%- match rft %>
<%- when Some with (rft) -%>
\section*{Refutation (classical logic)}

The proposition isn't provable in classical logic, thus neither in intuitionistic one.

You can confirm non-provability via the following refutation in boolean semantics.

<= rft.assignment %>
<%- when None -%>
<%- endmatch -%>
<%- when SolverResult::Unknown -%>
<%- endmatch -%>
<% match int_result %>
<%- when SolverResult::Provable with (pf) %>
<%- match pf %>
<%- when Some with (pf) -%>
\section*{Proof (intuitionistic logic)}

The proposition is provable in intuitionistic logic, thus provable too in classical one. Below is one such proof diagram.

<% for fragment in pf %>
<%- if pf.len() > 1 %>
\subsection*{<= fragment.name %>}
<%- endif %>
\begin{prooftree}
<= fragment.source -%>
\end{prooftree}
<% endfor %>

<%- when None %>
<%- endmatch %>

<%- when SolverResult::NotProvable with (rft) %>
<%- match rft %>
<%- when Some with (rft) -%>
\section*{Refutation (intuitionistic logic)}

The proposition isn't provable in intuitionistic logic.

You can confirm non-provability via the following refutation in Kripke semantics.

<= rft.frame %>
<= rft.assignment %>
<%- when None -%>
<%- endmatch -%>
<%- when SolverResult::Unknown -%>
<%- endmatch -%>

<%- endblock -%>


% !TEX root=/home/tavant/these/manuscript/src/manuscript.tex

\section{Collisionless kinetic model and polytropic state law}
  \label{sec-kinetic}

  The previous section showed that in the \ac{1D} \ac{PIC} simulations the electrons are not Maxwellian, similarly to the \ac{2D} results.
  In this section, we use the 1D kinetic equation in order to highlight the important phenomena needed to describe the sheath.

  \subsection{Vlasov equation for the sheath}

    Because the sheath is thin and the neutral pressure is low, we neglect the collisions in the sheath, so that we only need to solve Vlasov's equation.
    The stationary 1D-3V Vlasov equation for the EVDF reads\string:
    \begin{equation}\label{eq-vlasov}
      v_x \cdot \partial_x f_e \vec{e}_x + \frac{e}{m_e} \nabla \phi \cdot \nabla_v f_e = 0,
    \end{equation}
    Since the electrostatic potential depends only on $x$, \cref{eq-vlasov} becomes,
    \begin{equation}
    v_x \partial_x f_e +  \frac{e}{m_e}\partial_x\phi \partial_{v_x} f_e = 0
    \label{eq-vlasov1D}
    \end{equation}
    The variables $v_y$ and $v_z$ do not play any role, such that they can be hold constant, and we can solve \cref{eq-vlasov1D} with $f_e$ as a function of $x$ and $v_x$ only.

    In order to solve \cref{eq-vlasov1D} in the sheath,  we use the following boundary conditions\string:
      \begin{enumerate}
    \item At the plasma sheath boundary ($x=x_s$) the EEDF is imposed\string:
    \begin{equation}
    f_e(x_s, v_x) = f_0(v_x),
    \label{eq-plasma_BC}
    \end{equation}
    \item At the wall ($x=x_w$) the particles are absorbed, such that
    \begin{equation}
    f(x_w, v_x<0) = 0
    \label{eq-wall_BC}
    \end{equation}
    \end{enumerate}

    The partial derivative equation (\ref{eq-vlasov1D}) can be solved by the method of the characteristics. We introduce the function $\gamma(x)$ such that
    \begin{equation}
      \frac{df_e(x,\gamma(x))}{dx} = \partial_x f_e + \gamma' \partial_{v_x} f_e = 0
    \end{equation}
    Combining this equation with \cref{eq-vlasov1D} for $v_x = \gamma(x)$,
    \begin{equation}
      \label{eq-char}
      \left( \frac{e\phi'}{m_e} - \gamma \gamma' \right) \partial_{v_x} f_e = 0
    \end{equation}
    In general $\partial_{v_x} f_e \neq 0$ such that $(e\phi'/m_e - \gamma\gamma')$ can be integrated
    \begin{equation}
      \frac{\gamma(x)^2}{2} - \frac{e\phi(x)}{m_e} = \frac{\gamma(x_s)^2}{2} - \frac{e\phi_s}{m_e}
    \end{equation}
    Since the EVDF is conserved along the contour $\gamma$,
    \begin{equation}
      f_e(x,\gamma(x)) = f_e(x_s, \gamma(x_s))
    \end{equation}
    and
    \begin{equation}
      \gamma(x_s) = \left[ \gamma(x)^2 - \frac{2e(\phi(x) - \phi_s)}{m_e} \right]^{1/2}
    \end{equation}
    with $\phi_s$ the plasma potential at the sheath edge.
    Using \cref{eq-plasma_BC},
    \begin{equation}
      \label{eq-sol}
      f_e(x,v) = f_0\left( \left[ v^2 - \frac{2e(\phi(x) - \phi_s)}{m_e} \right]^{1/2}\right)
    \end{equation}
    Condition (\ref{eq-wall_BC}) yields a condition on $f_0$\string:
    \begin{equation}
      \label{eq-trunc}
      \text{for all } v > \left( \frac{2e\phi_s}{m_e} \right)^{1/2}, f_0(v) = 0
    \end{equation}

    This simple collisionless model explains rigorously how the tail of the EVDF is cut by the wall absorption.
    This asymmetry of the \ac{EVDF} could press us to separate the electrons into the population going toward the wall and the one going away from the wall.
    \Cref{fig-EVDFpm} shows the EEPF of the electron going toward and from the wall.
    We can see that there is only a small difference between the  EEPF of the two populations.
    Indeed, as the domain is symmetric and bounded in the two directions, the population coming toward the wall is also depleted by the opposite wall.
    Hence in the following, we will neglect this asymmetry due to the wall.

    \begin{figure}[!hbt]
      \centering
      \includegraphics[width=\defaultwidth]{EVDFpm.pdf}
      \caption{EEPF measured in the PIC simulations of the electrons going toward and from the wall at $x=23.7mm$. The green dashed line corresponds to a Maxwellian distribution of 5$\eV$.}
      \label{fig-EVDFpm}
    \end{figure}

    \begin{figure}[!hbt]
      \centering
      \includegraphics[width=\defaultwidth]{EVDFshift.pdf}
      \caption{Evolution of the EEPF between 1.3mm (in blue) and 23.7mm (in orange) from the wall. Is overlaid (in dashed green) the expected  EEPF at $x=1.3$mm using the EEPF at $x=23.7$mm and the potential difference in \cref{eq-sol}. }
      \label{fig-PICEEPF}
    \end{figure}

    \Cref{fig-PICEEPF} compares the EEPF from \cref{eq-sol} with the \ac{PIC} simulations between the position $x=1.3$\,mm and $x=23.7$\,mm.
    The plasma potential reads $\phi(x=1.3\,{\rm mm})=4.1$\,V and  $\phi(x=23.7\,{\rm mm})=7.7$\,V.
    We can observe a very good agreement between the actual evolution of the EEPF measured in the simulations and the prediction of \cref{eq-sol}.
    This confirms the possibility to neglect the collisions in the sheath.

  \subsection{Polytropic state law for the electrons}

    The evolution of a two-$\Te$ EEDF  in a collisionless potential drop has been studied by \citet{zhang2016}.
    The authors have shown that the evolution of the electron population can be described using a polytropic index $\gamma$, such that\string:
    \begin{equation}
      \label{eq-poly}
      \nabla_x \left( p_{e,x}(x) n_e(x)^{-\gamma} \right)= 0
    \end{equation}
    with $p_{e,x}=n_e \Te{}_{,x}$ the electron pressure in the $x$ direction.
    The value of $\gamma$ is related to the two temperatures $T_1$ and $T_2$, and for $T_1 > T_2$, we have $\gamma > 1 $.

    \begin{figure}[!htb]
      \centering
      \includegraphics[width =\defaultwidth]{Polytropic.pdf}
      \caption{Electron pressure as a function of the electron density observed in the PIC simulations of \cref{fig-PIC1} (black markers), and the linear fit (blue dotted line) in order to determine $\gamma$.}
      \label{fig-polyFit}
    \end{figure}

    \Cref{fig-polyFit} shows the PIC simulation results presented in \cref{fig-PIC1} in log scale.
    Each marker represents one cell of the PIC simulation.
    Overlaid is a linear regression which slope is the polytropic index $\gamma$.
    The regression is conducted over the whole simulation domain.
    We can see that the linear regression fits the simulation results with a very good agreement (R$^2$ = 0.999).
    The value $\gamma = 1.43$ is significantly higher than the isothermal case ($\gamma_{\rm isothermal} = 1$).
    Interestingly, while the polytropic law observed in \citet{zhang2016} was only for a collisionless evolution, here the polytropic law is observed in both the collisionless sheath and the weakly collisional plasma region.

    The polytropic law of \cref{eq-poly} can be used in order to close the fluid equation without the isothermal hypothesis.
    The non-isothermal fluid model for the sheath is the subject of \cref{sec-fluid}.
    A polytropic index for the ions has already been proposed in order to link the ions kinetics and the fluid parameters \citep{kuhn2006,jelic2007}.
    The approach here is essentially the same but applied to the electrons.

  \subsection{Evolution of the polytropic index}
    \label{subsec-presurseffect}
    We investigate the effect of the neutral pressure on the polytropic index $\gamma$ for the 5 pressure conditions of \cref{tab_1DPICParams}.
    We recall that the electron elastic scattering and momentum transfer are modeled, while the ionization and the heating are not self-consistent, but they are similar to the \ac{2D} \ac{PIC} models of \cref{ch-2}.
    \Cref{fig-p} presents the evolution of $\gamma$ as a function of the pressure.
    We can see that the polytropic index decreases from 1.7 to 1.4 as the pressure increases from 0.05 to 10 mTorr.
    This is in agreement with the fact that the high energy electron population is mostly replenished by the electron-neutral scattering, in agreement with \citet{kaganovich2007}.
    Increasing the collisions while keeping the other parameters constant provides more electrons to the high energy tail, hence reducing the polytropic index, as observed by \citet{zhang2016}.

    \begin{figure}[!htb]
      \centering
      \includegraphics[width=\defaultwidth]{pressur_effectLog.pdf}
      \caption{Effect of the background neutral pressure over the polytropic index $\gamma$ in the \acs{1D} \acs{PIC} simulations, under the conditions of \cref{tab_1DPICParams}. As a reminder, the isothermal case corresponds to $\gamma=1$.}
      \label{fig-p}
    \end{figure}

    Other parameters are also expected to modify $\gamma$.
    For instance the size of the simulation, the electron mean energy, and the nature of the gas.

  \subsection{Coulomb collision and possible improvements}

    In the \ac{PIC} simulations, the Coulomb collisions (electron-electron, electron-ion, and ion-ion) are not modeled.
    However, they are known to modify the distribution function.
    More precisely, they isotropize the distribution and tend toward a Maxwellian \citep{bhatnagar1954,sydorenko2006b}.

     Using the density $n_e=\sn{1}{15}\,\per\meter\cubed$ and the electron temperature $\Te=3\,\volt$ we find the electron-electron Coulomb collision at 90$^{\circ}$ \citep{lieberman2005,chen2006}
     \begin{equation} \label{eq-nu_Coulomb}
       \nu_{90} = 15 \,\kilo\hertz
     \end{equation}
     which is significantly smaller than the electron-neutral scattering frequency.
     However, it is known that the Coulomb collisions cross-section is highly dependent on the electron velocity.

     \Cref{fig-mfp_coulomb} shows the evolution of the mean free path for the electron-electron Coulomb collision $l_{CC} = v_e/\nu_{90}$.
     We can see that it is of the order of the domain size ($L=10\,\centi\meter$) only for very low energy.
     \begin{figure}[!hbt]
       \centering
       \includegraphics[width=\defaultwidth]{Coulomb_collision_meanfreepath_zoom}
       \caption{Mean free paths of the Coulomb collision as a function of the electron energy.}
       \label{fig-mfp_coulomb}
     \end{figure}
     On the other hand, the collision frequency for small angle is higher.
     In \citet{sydorenko2006b}, the authors showed that under some conditions, the Coulomb collisions can modify the simulation results by a few tens of percent.
     Hence, the impact of the small angle Coulomb collisions on the distribution functions should be asserted in future work.
     Modeling the Coulomb collision in \ac{PIC} simulations currently require a different model than the \ac{MCC} algorithm, thus requires more time to be implemented and tested before being used.


\documentclass[11pt]{article}
\usepackage{cctbx_preamble}
\usepackage{amscd}
\usepackage[title]{appendix}

\title{Merging of equivalent reflections}
\author{\lucjbourhis}
\date{\today}

\begin{document}
\maketitle

Two steps are required to merge equivalent reflections with the \cctbx . Given a \code{miller.array} \code{m},
\begin{enumerate}
\item \code{m1 = m.map\_to\_asu()} projects each Miller index into the asymmetric unit, i.e. for each group of equivalent reflection, each index of that group is replaced by the same Miller index;
\item \code{merging = m1.merge\_equivalents()} finds the group of identical Miller indices, gathers the data and sigma's for each group in turn, computes an average datum and an associated sigma; \code{merging.array()} is then the \code{miller.array} containing those unique indices associated to those averaged data and sigma.
\end{enumerate}
The first step is only about space-group algebra whereas the second step is only about statistics and this division is therefore optimally orthogonal in a sense. We will now expound each step, starting from the second one.

\section{Averaging of equivalent reflections}

Given $n$ data $y_1, \ldots, y_n$ and the associated estimated standard deviations $\sigma_1, \ldots, \sigma_n$, either the amplitudes or the intensities for a group of symmetry equivalent reflections, we sought to combine those data and sigma's into a single datum and an associated standard deviation.

That merged amplitude or intensity $\bar{y}$ is computed as a weighted average of the $\{y_i\}_{i=1,\ldots,n}$,
\begin{equation}
\bar{y} = \frac{\sum_{i=1}^n w_i y_i}{\sum_{i=1}^n w_i} .
\label{eqn:average}
\end{equation}
There are two ways to handle this from a statistical point of view.

\subsection{External variance}

The first one gives a mathematical meaning to the loose assertion that all $y_i$ should be equal within the uncertainties quantified by the $\sigma_i$ (the exact equality is required by those being equivalent reflections but this is spoiled by all sources of errors in measurement and data processing up to this point). Each $y_i$ is then seen as an outcome of a random variable $\hat{y}_i$ which is an unbiased estimator for the value $y_{\text{eq}}$ that all equivalent reflections should ideally share, i.e. mathematically
\begin{align}
E(\hat{y}_i) &= y_{\text{eq}}, \ \forall i=1,\ldots,n\\
V(\hat{y}_i) &= \sigma_i^2 \nonumber.
\end{align}
Then the average $\bar{y}$ is the outcome of the random variable
\begin{equation}
\hat{y} = \frac{\sum_{i=1}^n w_i \hat{y}_i}{\sum_{i=1}^n w_i} .
\end{equation}
which is obviously an unbiased estimator of $y_{\text{eq}}$ (i.e. $E(\hat{y}) = y_{\text{eq}}$). If we postulate that the measurement and data reduction lead to uncorrelated $\hat{y}_i$, then
\begin{align}
V(\hat{y}) &=  \sum_{i=1}^n \omega_i^2 V(\hat{y}_i)\\
\intertext{where}
\omega_i &= \frac{w_i}{\sum_{i=1}^n w_i}.
\label{eqn:externalvariance}
\end{align}
This is often called the ``external'' variance. Its lowest possible value is obtained for the weights
\begin{equation}
\tilde{w}_i = \frac{1}{V(\hat{y}_i)} = \frac{1}{\sigma_i^2},
\label{eqn:minimalvarianceweights}
\end{equation}
as well as for any weights differing from those by a common proportionality factor, as demonstrated in appendix~\ref{apendixa} and this minimum is equal to
\begin{equation}
V(\hat{y}) = \frac{1}{\sum_{i=1}^n \tilde{w}_i} = \frac{1}{n\mean{\tilde{w}_i}}.
\end{equation}
Those are the weights and the external variance used by the \code{cctbx}.

This is not the only popular choice. Indeed ShelXL \cite{SHELX:man97} uses instead
\begin{equation}
w_i = \begin{cases}
\frac{y_i}{\sigma_i^2} & \text{if}\ \frac{y_i}{\sigma_i} > 3,\\
\frac{3}{\sigma_i} & \text{otherwise}.
\end{cases}
\end{equation}

\subsection{Internal variance}

The second way to handle the \eqnref[name=average~]{average} is to consider it as a mere sample mean, but a weighted one, ignoring the special property of the $y_i$. Those data are considered as the outcome of a sample $(Y_1, \ldots, Y_n)$ of a random variable $Y$, and $\bar{y}$ is then the outcome of the unbiased estimator of $E(Y)$,
\begin{equation}
\bar{Y} = \frac{\sum_{i=1}^n w_i Y_i}{\sum_{i=1}^n w_i}.
\end{equation}
It is then natural to also compute a weighted sample variance
\begin{align}
S^2 &= \frac{\sum_{i=1}^n w_i (Y_i - \bar{Y})^2}{\sum_{i=1}^n w_i}.
\label{eqn:biasedsamplevariance}
\intertext{However, it is a biased estimator of $V(Y)$, as it is well-known in the unweighted case, i.e. all weights $w_i$ equal. The unbiased estimator}
S^2_{n-1} &= \frac{S^2}{1-\sum_{i=1}^n \omega_i^2}\\
& = \frac{\sum_{i=1}^n w_i}{\left(\sum_{i=1}^n w_i\right)^2 - \sum_{i=1}^n w_i^2} \sum_{i=1}^n w_i (Y_i - \bar{Y})^2
\label{eqn:unbiasedsamplevariance}
\end{align}
is therefore preferred. Those variances are called ``internal'' as opposed to the variance we have previously discussed. The \code{cctbx} computes it by using an instance of \code{scitbx::mean\_and\_variance} and calling its member function \code{gsl\_stats\_wvariance} whose implementation and naming follows the function with the same name in the GNU Scientific Library~\cite{GSL}. Since this formula is not that easily found in textbooks, we demonstrate it in appendix~\ref{appendixb}.

Finally, it is customary to estimate the variance associated with $\bar{y}$ by taking the greatest of the internal and external variance. That is what the \code{cctbx} does as well as ShelXL.

\begin{appendices}
\section{Minimum variance weights}
\label{apendixa}

We will demonstrate \eqnref{minimalvarianceweights}. We seek the solution of the constrained minimisation problem
\begin{align}
&\min V(\hat{y}),\\
&V(\hat{y}) = \sum_{i=1}^n \omega_i^2 V(\hat{y}_i),\\
&\sum_{i=1}^n \omega_i = 1.
\label{eqn:omegaconstraint}
\end{align}
We can solve it by minimising the Lagrangian
\begin{align}
L &= V(\hat{y}) - \lambda \sum_{i=1}^n \omega_i,\\
  &= \sum_{i=1}^n \left[V(\hat{y}_i)\left(\omega_i - \frac{\lambda}{2V(\hat{y}_i)} \right)^2 - \frac{\lambda^2}{4V(\hat{y}_i)} \right]
\end{align}
Thus $L$ reaches its minimum at
\begin{align}
\omega_i &= \frac{\lambda}{2V(\hat{y}_i)}\\
\intertext{and using \eqnref{omegaconstraint}, it comes}
\frac{\lambda}{2} &= \frac{1}{\sum_{i=1}^n \frac{1}{V(\hat{y}_i)}}\\
\intertext{and therefore the minimum is reached at}
\omega_i &= \frac{\frac{1}{V(\hat{y}_i)}}{\sum_{j=1}^n \frac{1}{V(\hat{y}_i)}}.
\end{align}
That demonstrates \eqnref{minimalvarianceweights} and since weights differing by a common proportionality factor yield the same $\omega_i$, QED.

\section{Weighted sample variance}
\label{appendixb}
First let us remember that, by definition of a sample,
\begin{align}
E(Y_i) &= E(Y),\ \forall i=1,\ldots, n\\
V(Y_i) &= V(Y)
\end{align}
Therefore,
\begin{align*}
V(Y) &= \sum_{i=1}^n \omega_i V(Y_i)\\
      &= E\left[ \sum_{i=1}^n \omega_i(Y_i - E(Y))^2 \right]\\
      &= E\left[ \sum_{i=1}^n \omega_i(Y_i - \bar{Y})^2 \right]
      + 2 E\left[ \sum_{i=1}^n \omega_i(Y_i - \bar{Y})(\bar{Y} - E(Y)) \right]
      +  \sum_{i=1}^n \omega_i E\left[ (\bar{Y} - E(Y))^2 \right]
\end{align*}
Then,
\begin{itemize}
\item since $E(\bar{Y}) = E(Y)$, the last term is $V(\bar{Y})$;
\item by definition of $\bar{Y}$, $\sum_{i=1}^n \omega_i(Y_i - \bar{Y})=0$ and the second term is therefore 0.
\end{itemize}
Thus
\begin{align}
V(Y) &= E(S^2) + V(\bar{Y}).\\
\intertext{But}
V(\bar{Y}) &= \sum_{i=1}^n \omega_i^2 V(Y)\\
\intertext{and therefore}
V(Y) &= \frac{E(S^2)}{1-\sum_{i=1}^n \omega_i^2}
\end{align}
\end{appendices}

\bibliography{cctbx_references}

\end{document}


%%------------------------ SI units -------------------------------
\DeclareSIUnit\udensity{\kilo \gram \per \cubic \metre}
\DeclareSIUnit\uacceleration{\metre \per \square \second}
\DeclareSIUnit\uvelocity{\metre \per \second}
\DeclareSIUnit\uviscosity{\pascal \second}
\DeclareSIUnit\ubetaT{\per \kelvin}
\DeclareSIUnit\ubetawl{\per \ucomposition}
\DeclareSIUnit\udiffusivity{\metre \squared \per \second}
\DeclareSIUnit\uconductivity{\watt \per \metre \per \kelvin}
\DeclareSIUnit\uhconvec{\watt\per \square \metre \per \kelvin}
\DeclareSIUnit\umasscapacity{\joule \per \kilo\gram \per \kelvin}
\DeclareSIUnit\umassenergy{\joule \per \kilo\gram}
\DeclareSIUnit\uvolumecapacity{\joule \per \cubic \metre \per \kelvin}
\DeclareSIUnit\uvolumeenergy{\joule \per \cubic \metre}
\DeclareSIUnit\udegC{\degreeCelsius}
\DeclareSIUnit\udegK{\kelvin}
\DeclareSIUnit\uCR{\kelvin \per \second}
\DeclareSIUnit\ugradT{\kelvin\per\milli\metre}
\DeclareSIUnit\utime{\second}
\DeclareSIUnit\uarea{\square \metre}
\DeclareSIUnit\uvolume{\cubic \metre}

\DeclareSIUnit\ucomposition{wt.\%}  % used in tables
\DeclareSIUnit\uslope{\udegK \per \ucomposition}  % used in tables
\newcommand\bin[3]{#1-\SI{#2}{\ucomposition} #3}	% used in text
\newcommand\tern[5]{#1-\SI{#2}{\ucomposition} #3-\SI{#4}{\ucomposition} #5} % used in text
\newcommand\orient[3]{\ensuremath{\brac{\ang{#1},\ang{#2},\ang{#3}}}}	% typset grain orientation

%% ------------------------ MATHs commands--------------------------
%\renewcommand{matrix}[1]{#1 \rangle}
\newcommand{\avg}[1]{\ensuremath{\left \langle  #1 \right \rangle}}
\newcommand{\brac}[1]{\ensuremath{\left(  #1 \right)}}
\newcommand{\curly}[1]{\ensuremath{\left\{  #1 \right\}}}
\newcommand{\crochet}[1]{ \left[  #1  \right] }
\newcommand{\abval}[1]{\ensuremath{\left |  #1 \right |}}
\newcommand\norm[1]{\ensuremath{\lVert #1 \rVert}}

\renewcommand\d{\ensuremath{\partial}}
\newcommand\integral[3]{\ensuremath{\int_{#1} #2\: \mathrm{d}#3}}
\newcommand{\deriv}[1]{\frac{\partial #1 }{\partial t}}
\newcommand{\diff}[2]{ \ensuremath{\nabla \cdot \brac{ #1 \nabvec #2}}}
\newcommand\temp[1]{\ensuremath{\frac{\partial}{\partial t} \brac{#1} }}
\newcommand\tempup[1]{\ensuremath{\frac{\partial #1}{\partial t} }}

%\newcommand{\mtrx}[1]{{\underline{\underline{#1}}} }
\newcommand{\mtrx}[1]{{\overline{\overline{#1}}} }
\newcommand{\mat}[1]{{\overline{\overline{#1}}} }

\newcommand{\tausupg}{\ensuremath{\tau_\text{SUPG}}}
\newcommand{\taupspg}{\ensuremath{\tau_\text{PSPG}}}
\newcommand{\taulsic}{\ensuremath{\tau_\text{LSIC}}}

\newcommand\hilbert{\ensuremath{\mathscr{H}^1}}
\newcommand\order{\ensuremath{\mathscr{O}}}
\newcommand\test{\ensuremath{\mathscr{W}}}
\newcommand\interp{\ensuremath{\mathscr{P}}}
\newcommand\Mij{\ensuremath{\mathscr{M}_{ij}}}
\newcommand\Aij{\ensuremath{\mathscr{A}_{ij}}}
\newcommand\Kija{\ensuremath{\mathscr{K}1_{ij}}} % diffusion term
\newcommand\Kijb{\ensuremath{\mathscr{K}2_{ij}}} % boundary condition
\newcommand\Fi{\ensuremath{\mathscr{F}_{i}}}
\newcommand\Qi{\ensuremath{\mathscr{Q}_{i}}}
\newcommand\Ohm{\ensuremath{\Omega}}
\newcommand\dOhm{\ensuremath{\partial \Ohm}}
\newcommand\OhmE{\ensuremath{\Ohm_E}}
\newcommand\dOhmE{\ensuremath{\partial \OhmE}}
\newcommand\element{\ensuremath{\Ohm_E}}
\newcommand\brent{\ensuremath{{\brac{\tau}}}}
\newcommand\brentplus{\ensuremath{{\brac{\tau+1}}}}
\newcommand\brentzero{\ensuremath{{\brac{\tau=0}}}}
%--------------------------
\newcommand\itersymbol{\nu}
%--------------------------
\newcommand\iter{\ensuremath{{\brac{\itersymbol}}}}
\newcommand\iterplus{\ensuremath{{\brac{\itersymbol+1}}}}
\newcommand\iterminus{\ensuremath{{\brac{\itersymbol-1}}}}
\newcommand\dRdH{\ensuremath{\frac{\partial R}{\partial H}}}
\newcommand\dRdT{\ensuremath{\frac{\partial R}{\partial T}}}
\newcommand\dTdH{\ensuremath{\frac{\partial T}{\partial H}}}
\newcommand\dTdHjt{\ensuremath{\brac{\partial T/\partial H}_j^{t}}}
\newcommand\dTdHjk{\ensuremath{\brac{\partial T/\partial H}_j^{\iter}}}
\newcommand\dTdHjkplus{\ensuremath{\brac{\partial T/\partial H}_j^{\iterplus}}}
\newcommand\dHdT{\ensuremath{\frac{\partial H}{\partial T}}}
\newcommand\dHdTjk{\ensuremath{\brac{\partial H/\partial T}_j^{\iter}}}
\newcommand\dHdTjkplus{\ensuremath{\brac{\partial H/\partial T}_j^{\iterplus}}}
\newcommand\dHdTjt{\ensuremath{\brac{\partial H/\partial T}_j^{t}}}
\newcommand\dRdTijk{\ensuremath{\brac{\frac{\partial R}{\partial T}}_{ij}^{\iter}}}
\newcommand\dRdHijk{\ensuremath{\brac{\frac{\partial R}{\partial H}}_{ij}^{\iter}}}
\newcommand\Rjk{\ensuremath{R_{j}^{\iter}}}

\newcommand\nabvec{\ensuremath{\vec{\nabla}}}
\newcommand\nabmat{\ensuremath{\mat{\nabla}}}
\newcommand\nabmattransp{\ensuremath{\mat{\nabla^\text{t}}}}
\newcommand\vit{\ensuremath{\avg{\vl}}}
\newcommand\vitf{\ensuremath{\avg{\vf}}}
\newcommand\vita{\ensuremath{\avg{\va}}}
\newcommand\strainrateliq{\ensuremath{\avg{\mat{\dot{\varepsilon}^l}}}}
\newcommand\strainrate{\ensuremath{\mat{\dot{\varepsilon}}}}
\newcommand\I{\ensuremath{\mat{\mathrm{I}}}}

%TODO :redundant defnitions rh and rhoh
%TODO :redundant defnitions rhv and rhohv
\renewcommand\r{\ensuremath{\avg{ \rho }}}
\newcommand\rl{\ensuremath{\avg{ \rho }^l}}
\newcommand\h{\ensuremath{\avg{ h }}}
\newcommand\rh{\ensuremath{\avg{ \rho h }}}
\newcommand\rhoh{\ensuremath{\avg{ \rho h }}}
\newcommand\rhv{\ensuremath{\avg{ \rho h \vec{v} }}}
\newcommand\rhohv{\ensuremath{\avg{ \rho h \vec{v} }}}
\newcommand\rcp{\ensuremath{\avg{ \rho C_p }}}

\newcommand\w{\ensuremath{\avg{w}}}
\newcommand\wi{\ensuremath{\avg{w_i}}}
%\newcommand\wil{\ensuremath{\avg{w_i}^l}}
\newcommand\wil{\ensuremath{w_i^l}}
\newcommand\wis{\ensuremath{w_i^s}}
\newcommand\gphi{\ensuremath{{g^{\phi}} }}
\newcommand\wiphi{\ensuremath{\wi^\phi}}
\newcommand\rphi{\ensuremath{\avg{\rho}^{\phi} }}
\newcommand\hphi{\ensuremath{\avg{h}^{\phi} }}
\newcommand\Tk{\ensuremath{T^\iter}}
\newcommand\Tkplus{\ensuremath{T^\iterplus}}
\newcommand\Tkinit{\ensuremath{T^{\brac{k=0}}}}
\newcommand\Hk{\ensuremath{\rh^{\brac{k}}}}
\newcommand\Hkinit{\ensuremath{\rh^{\brac{k=0}}}}
\newcommand\source{\ensuremath{\avg{\dot{Q}_{{V}}}}}
\newcommand\Hj{\ensuremath{H_j}}
\newcommand\Hjt{\ensuremath{H_j^t}}
\newcommand\Hjk{\ensuremath{H_j^\iter}}
\newcommand\Hjkminus{\ensuremath{H_j^{\iterminus}}}
\newcommand\Hjkplus{\ensuremath{H_j^{\iterplus}}}
\newcommand\Hkplus{\ensuremath{H^{\iterplus}}}
\newcommand\Hjtminus{\ensuremath{H_j^{t-\dt}}}
\newcommand\Hjtplus{\ensuremath{H_j^{t+\dt}}}
\newcommand\deltaHk{\ensuremath{\Delta H^\iter}}
\newcommand\deltaHkplus{\ensuremath{\Delta H^\iterplus}}
\newcommand\Tj{\ensuremath{T_j}}
\newcommand\Tjt{\ensuremath{T_j^t}}
\newcommand\Tjk{\ensuremath{T_j^\iter}}
\newcommand\Tjkminus{\ensuremath{T_j^{\iterminus}}}
\newcommand\Tjkplus{\ensuremath{T_j^{\iterplus}}}
\newcommand\Tjtminus{\ensuremath{T_j^{t-\dt}}}
\newcommand\Tjtplus{\ensuremath{T_j^{t+\dt}}}
\newcommand\nosum{\text{no sum on }j}

%TODO :redundant defnitions rhoref and rref
\newcommand\rhoref{\ensuremath{\rho_{\text{ref}}}}
\newcommand\rref{\ensuremath{\rho_{\text{ref}}}}
\newcommand\rholref{\ensuremath{\rho_{0}^{l}}}
\newcommand\Tref{\ensuremath{T_{0}}}
\newcommand\wlref{\ensuremath{w_{0}^l}}
\newcommand\wilref{\ensuremath{\wi_{0}^l}}
\newcommand\betaT{\ensuremath{\beta_T}}
\newcommand\betawl{\ensuremath{\beta_{\wl}}}
\newcommand\betawil{\ensuremath{\beta_{\wil}}}
\newcommand\betawlC{\ensuremath{\beta_{\avg{w_\text{C}}^l}}}
\newcommand\betawlCR{\ensuremath{\beta_{\avg{w_\text{Cr}}^l}}}

\newcommand\wavg{\ensuremath{\avg{w}}}
\newcommand\wC{\ensuremath{\avg{w_\text{C}}}}
\newcommand\wCR{\ensuremath{\avg{w_\text{Cr}}}}
\newcommand\wl{\ensuremath{\avg{w}^l}}
\newcommand\ws{\ensuremath{\avg{w}^s}}
\newcommand\wa{\ensuremath{\avg{w}^a}}
\newcommand\Cnominal{\ensuremath{{w}_0}}
\newcommand\Cl{\ensuremath{{w}^l}}
\newcommand\Clstar{\ensuremath{{w}^{l \text{*}} }}
\newcommand\Cs{\ensuremath{{w}^s}}
\newcommand\Csstar{\ensuremath{{w}^{s \text{*}} }}

\renewcommand\k{\ensuremath{k}}
\newcommand\ml{\ensuremath{{m}^l}}
\newcommand\ms{\ensuremath{{m}^s}}
\newcommand\pdas{\ensuremath{{\lambda}_{1}}}
\newcommand\sdas{\ensuremath{{\lambda}_{2}}}
\newcommand\Tcoh{\ensuremath{{T}_{\text{coh}}}}
\newcommand\Fos{\ensuremath{\text{Fo}^s}} % Fourier number in the solid
\newcommand\tsolidif{\ensuremath{t_\text{s}}} % solidification time in Fourier number
\newcommand\rev{\ensuremath{V_\text{E}}} % V_\text{RVE}
\newcommand\Vs{\ensuremath{V^s}}
\newcommand\Vl{\ensuremath{V^l}}
\newcommand\Vphi{\ensuremath{V^\phi}}
\newcommand\psis{\ensuremath{\avg{\psi}^s}}
\newcommand\psil{\ensuremath{\avg{\psi}^l}}
\newcommand\gammastar{\ensuremath{{\Gamma}^{\text{*}} }}

\newcommand\rhoM{\ensuremath{\avg{\rho}^M}}
\newcommand\rhoA{\ensuremath{\avg{\rho}^A}}
\newcommand\rhof{\ensuremath{\avg{\rho}^F}}
\newcommand\rhoa{\ensuremath{\avg{\rho}^a}}
\newcommand\rhol{\ensuremath{\avg{\rho}^l}}
\newcommand\rhos{\ensuremath{\avg{\rho}^s}}
\newcommand\rhov{\ensuremath{\avg{\rho \vec{v}}}}
\newcommand\rholvl{\ensuremath{\rho^l \vl}}
\newcommand\rhosvs{\ensuremath{\rho^s \vs}}
\newcommand\cp{\ensuremath{C_p}}
\newcommand\cpl{\ensuremath{C_p^l}}
\newcommand\cps{\ensuremath{C_p^s}}
\newcommand\cpa{\ensuremath{C_p^A}}
\newcommand\ka{\ensuremath{\avg{\kappa}^a}}  % I added \avg
\newcommand\kl{\ensuremath{\avg{\kappa}^l}}  % I added \avg
\newcommand\ks{\ensuremath{\avg{\kappa}^s}}	 % I added \avg
\newcommand\hf{\ensuremath{\avg{h}^F}}
\newcommand\ha{\ensuremath{\avg{h}^a}}
\newcommand\hl{\ensuremath{\avg{h}^l}}
\newcommand\hs{\ensuremath{\avg{h}^s}}
\newcommand\gf{\ensuremath{{g^F}}} % double braces useful for additional superscripts
\newcommand\ga{\ensuremath{{g^a}}} % double braces useful for additional superscripts
\newcommand\gl{\ensuremath{{g^l}}} % double braces useful for additional superscripts
\newcommand\gs{\ensuremath{{g^s}}} % double braces useful for additional superscripts
\newcommand\fl{\ensuremath{{f^l}}} % double braces useful for additional superscripts
\newcommand\fs{\ensuremath{{f^s}}} % double braces useful for additional superscripts
\newcommand\pf{\ensuremath{{p^F}}}
\newcommand\pa{\ensuremath{{p^a}}}
\newcommand\pl{\ensuremath{{p^l}}}
\newcommand\ps{\ensuremath{p^s}}
\newcommand\Da{\ensuremath{D^a}}
\newcommand\Dl{\ensuremath{D^l}}
\newcommand\Ds{\ensuremath{D^s}}
\newcommand\Dphi{\ensuremath{D^\phi}}
\newcommand\mua{\ensuremath{\mu^a}}
\newcommand\mul{\ensuremath{\mu^l}}
\newcommand\mus{\ensuremath{\mu^s}}
\newcommand\K{\ensuremath{\mathbb{K}}} %permeability
\newcommand\Kmodif{\ensuremath{\widetilde\K}} %permeability modified for level set
\newcommand\sigmaa{\ensuremath{\mat{\sigma^a}}}
\newcommand\sigmal{\ensuremath{\mat{\sigma^l}}}
\newcommand\sigmas{\ensuremath{\mat{\sigma^s}}}

%interfaces (extra spaces are on purpose)
\newcommand\liqsol{\ensuremath{l\text{-}s}}
\newcommand\liqair{\ensuremath{l\text{-}a}}
\newcommand\solair{\ensuremath{s\text{-}a}}
\newcommand\vliqsol{\ensuremath{\vec{v^{\liqsol}}}}
\newcommand\vliqair{\ensuremath{\vec{v^{\liqair}}}}
\newcommand\vsolair{\ensuremath{\vec{v^{\solair}}}}
%\newcommand\vliqsol{\ensuremath{\vec{v}^{\liqsol}}}
%\newcommand\vliqair{\ensuremath{\vec{v}^{\liqair}}}
%\newcommand\vsolair{\ensuremath{\vec{v}^{\solair}}}
\newcommand\nliqsol{\ensuremath{\vec{n^{\liqsol}}}}
\newcommand\nliqair{\ensuremath{\vec{n^{\liqair}}}}
\newcommand\nsolair{\ensuremath{\vec{n^{\solair}}}}

%\newcommand\vf{\ensuremath{\vec{v}^F}}
%\newcommand\va{\ensuremath{\vec{v}^a}}
%\newcommand\vl{\ensuremath{\vec{v}^l}}
%\newcommand\vs{\ensuremath{\vec{v}^s}}
%\newcommand\vphi{\ensuremath{\vec{v}^\phi}}
%\newcommand\vphistar{\ensuremath{\vec{v}^{\phi_1/\phi_2}}}
%\newcommand\vstar{\ensuremath{\vec{v}^\text{*}}}
%\newcommand\vlstar{\ensuremath{\vec{v}^{l \text{*}}}}
%\newcommand\vsstar{\ensuremath{\vec{v}^{s \text{*}}}}
\newcommand\vf{\ensuremath{\vec{v^F}}}
\newcommand\va{\ensuremath{\vec{v^a}}}
\newcommand\vl{\ensuremath{\vec{v^l}}}
\newcommand\vs{\ensuremath{\vec{v^s}}}
\newcommand\vM{\ensuremath{\avg{\vec{v}}^M}}
\newcommand\vA{\ensuremath{\avg{\vec{v}}^A}}
\newcommand\vphi{\ensuremath{\vec{v^\phi}}}
\newcommand\vphistar{\ensuremath{\vec{v^{\phi_1/\phi_2}}}}
\newcommand\vstar{\ensuremath{\vec{v^\text{*}}}}
\newcommand\vlstar{\ensuremath{\vec{v^{l \text{*}}}}}
\newcommand\vsstar{\ensuremath{\vec{v^{s \text{*}}}}}

\newcommand\gravity{\ensuremath{\vec{\text{g}}}}

\newcommand\dt{\ensuremath{\Delta t}}
\newcommand\hext{\ensuremath{h_{\text{ext}}}}
\newcommand\Text{\ensuremath{T_{\text{ext}}}}
\newcommand\Ttop{\ensuremath{T_{\text{Top}}}}
\newcommand\Tbottom{\ensuremath{T_{\text{Bottom}}}}

\newcommand*\widefbox[1]{\fbox{\hspace{2em}#1\hspace{2em}}}

% From "Mixing Boussinesq" report
%\renewcommand\v{\ensuremath{\vec{v}}}
\newcommand\Fv{\ensuremath{\vec{F}_{\text{v}}^l}}
\newcommand\rhog{\ensuremath{\rho \vec{g}}}
\newcommand\rhobouss{\ensuremath{\widetilde{\rho}}}
\newcommand\heaviside{\ensuremath{H}}
\newcommand{\heavisideM}{ \ensuremath{\heaviside^M}}
\newcommand{\heavisideA}{ \ensuremath{\heaviside^A}}
\newcommand\dirac{\ensuremath{\delta \brac{\levelset}}}
\newcommand\levelset{\ensuremath{\alpha}}
\newcommand\levelsettest{\ensuremath{\alpha^\text{*}}}
\newcommand\levelsetSUPG{\ensuremath{\alpha_{SUPG}^\text{*}}}
\newcommand\levelsetx{\ensuremath{\levelset \brac{\vec{x}}}}
\newcommand{\mix}[1]{\ensuremath{\widehat{#1}}} % \widehat % \overbrace % \widetilde

% Common nouns and names
\newcommand{\registered}{\textsuperscript{\textregistered}}
\newcommand{\cimlib}{\emph{CimLib }}
\newcommand{\thercast}{\emph{THERCAST\registered }}
\newcommand{\ccemlcc}{\emph{CCEMLCC }}
\newcommand{\doitpoms}{\emph{\copyright DoITPoMS, University of Cambridge}}
\newcommand\HtoT{$\text{H2T}$}
\newcommand\TtoH{$\text{T2H}$}
\newcommand\carbide{\ensuremath{\text{M}_7 \text{C}_3}}

% Colors
\newcommand{\red}[1]{{\color{Red} #1}}
\newcommand{\blue}[1]{{\color{Blue} #1}}
\newcommand{\green}[1]{{\color{Green} #1}}
\newcommand{\gray}[1]{{\color{Gray} #1}}

% List of acronyms
\usepackage{tabu}

\newcommand{\listofacronyms}{
\cleardoublepage
\section*{List of Acronyms}
%-----------------------------
{\footnotesize
{\tabulinesep=1.5mm
\begin{tabu}{p{2cm} p{12cm}}
\tabucline[1pt]{-}
\textbf{Acronym} & 	\textbf{Standing for} \\\tabucline[1pt]{-}
%-----------------------------
ALE		&	Arbitrary Lagrangian-Eulerian 	\\
BTR		& 	Brittle temperature range 		\\
CAFD	&	Cellular Automata Finite Difference \\
CAFE	&	Cellular Automata Finite Element\\
CBB		&	Circumventing Babuška-Brezzi	\\
CCEMLCC & 	Chill Cooling for the Electro-Magnetic Levitator in relation with Continuous Casting of steel \\
CEMEF 	& 	Centre de Mise en Forme des Matériaux 	\\
CFL		&	Courant–Friedrichs–Lewy 		\\
C.F.L	&	Computing and FLuids 			\\
CSF		&	Continuum Surface Force			\\
DLR		&	Deutsches Zentrum für Luft- und Raumfahrt  \\
DSPG	&	Darcy-Stabilising/Petrov-Galerkin \\
EML 	& 	Electromagnetic levitation 		\\
ESA 	& 	European Space Agency 			\\
FEM 	& 	Finite Element Method 			\\
FVM		&	Finite Volume Method			\\
GMAW	& 	Gas Metal Arc Welding			\\
ISS 	&	International Space Station 	\\
IWT		&	Institut für Werkstofftechnik 	\\
LHS		& 	Left-hand side					\\
LSIC	&	Least squares on incompressibility constraint \\
LSM		&	Level set method				\\
MAC		&	Marker-and-cell 				\\
%MIN	&	Mini-element 					\\
PF		&	Phase field 					\\
PSPG	&	Pressure-Stabilising/Petrov-Galerkin \\
RHS		& 	Right-hand side					\\
RUB		& 	Ruhr Universität Bochum 		\\
RVE		&	Representative Elementary Volume\\
SBB		&	Satisfying Babuška-Brezzi 		\\
%SCPG	& 	Shock Capturing Petrov-Galerkin	\\
SUPG	&	Streamline-Upwind/Petrov-Galerkin \\
VMS		&	Variational MultiScale			\\
VOF		&	Volume Of Fluid					\\\tabucline[1pt]{-}
%-----------------------------
\end{tabu}}
}
}
%--------------
\newlength{\largeur}
\newlength{\llargeur}
\newlength{\llargeurOut}
\newlength{\rlargeur}
\newlength{\rlargeurOut}
%---------------


\hypertarget{calibration}{%
\chapter{Calibration}\label{calibration}}

In the previous chapter, we replicated the analysis reported in
``Machine Bias'', by Julia Angwin, Jeff Larson, Surya Mattu and Lauren
Kirchner, published by ProPublica in May 2016.

After the ProPublica article, the Washington Post published a response
by Sam Corbett-Davies, Emma Pierson, Avi Feller and Sharad Goel: ``A
computer program used for bail and sentencing decisions was labeled
biased against blacks. It's actually not that clear.''.

I encourage you to read both of those articles before you go on. In this
chapter, I explain some of the arguments presented in the Washington
Post (WaPo) article, and we will replicate their analysis.

\hypertarget{the-wapo-response}{%
\section{The WaPo Response}\label{the-wapo-response}}

The Washington Post article summarizes the ProPublica article and the
response from Northpointe, the company that makes COMPAS, like this:

\begin{itemize}
\item
  ProPublica claims that COMPAS is unfair because ``among defendants who
  ultimately did not reoffend, blacks were more than twice as likely as
  whites to be classified as medium or high risk.''
\item
  Northpointe claims that COMPAS is fair because ``scores mean
  essentially the same thing regardless of the defendant's race. For
  example, among defendants who scored a seven on the COMPAS scale, 60
  percent of white defendants reoffended, which is nearly identical to
  the 61 percent of black defendants who reoffended.''
\end{itemize}

So ProPublica and Northpointe are invoking different definitions of
``fair''.

In the previous chapter we explored the first definition by computing
error rates (false positive and false negative) for white and black
defendants. In this chapter, we'll explore the second definition, which
is called ``calibration''.

\hypertarget{calibration-1}{%
\section{Calibration}\label{calibration-1}}

The WaPo article includes this figure, which shows ``white and black
defendants with the same risk score are roughly equally likely to
reoffend.''

\includegraphics{figs/calibration1.png}

To understand this figure, let's start by replicating it.

The following function groups defendants by risk score and computes the
fraction in each group that were charged with another crime within two
years.

\begin{lstlisting}[language=Python,style=source]
def calibration_curve(df):
    """Fraction in each risk group charged with another crime.

    df: DataFrame

    returns: Series
    """
    grouped = df.groupby('decile_score')
    return grouped['two_year_recid'].mean()
\end{lstlisting}

The following figure shows this calibration curve for all defendants and
for white and black defendants separately.

\begin{lstlisting}[language=Python,style=source]
cal_all = calibration_curve(cp)
cal_all.plot(linestyle='dotted',
              color='gray',
              label='All defendants')

white = (cp['race'] == 'Caucasian')
cal_white = calibration_curve(cp[white])
cal_white.plot(label='White')

black = (cp['race'] == 'African-American')
cal_black = calibration_curve(cp[black])
cal_black.plot(label='Black')

decorate(xlabel='Risk score',
         ylabel='Fraction charged with new crime',
         title='Recivism vs risk score, grouped by race')
\end{lstlisting}

\begin{center}
\includegraphics[scale=0.75]{02_calibration_files/02_calibration_21_0.pdf}
\end{center}

This figure shows that people with higher risk scores are more likely to
be charged with a new crime within two years. In that sense COMPAS works
as intended.

Furthermore, the test is equally calibrated for black and white
defendants; that is, in each risk group, the rate of recidivism is about
the same for black and white defendants.

The WaPo article explains why this is important:

\begin{quote}
A risk score of seven for black defendants should mean the same thing as
a score of seven for white defendants. Imagine if that were not so, and
we systematically assigned whites higher risk scores than equally risky
black defendants with the goal of mitigating ProPublica's criticism. We
would consider that a violation of the fundamental tenet of equal
treatment.
\end{quote}

So we want a test that has the same calibration for all groups, and we
want a test that has the same error rates for all groups. But there's
the problem: as the WaPo article explains, it is mathematically
impossible to be fair by both definitions at the same time.

To see why, let's go back to the confusion matrix.

\hypertarget{matrices-and-metrics}{%
\section{Matrices and Metrics}\label{matrices-and-metrics}}

In the previous chapter, we computed confusion matrices for white and
black defendants. Here they are again:

\begin{lstlisting}[language=Python,style=source]
matrix_white = make_matrix(cp[white])
matrix_white
\end{lstlisting}

\begin{tabular}{lrr}
\toprule
Actual &  Condition &  No Condition \\
Predicted &            &               \\
\midrule
Positive  &        505 &           349 \\
Negative  &        461 &          1139 \\
\bottomrule
\end{tabular}

\begin{lstlisting}[language=Python,style=source]
matrix_black = make_matrix(cp[black])
matrix_black
\end{lstlisting}

\begin{tabular}{lrr}
\toprule
Actual &  Condition &  No Condition \\
Predicted &            &               \\
\midrule
Positive  &       1369 &           805 \\
Negative  &        532 &           990 \\
\bottomrule
\end{tabular}

And here are the metrics we computed from the confusion matrices:

\begin{lstlisting}[language=Python,style=source]
metrics_white = compute_metrics(matrix_white,
                                'White defendants')
metrics_white
\end{lstlisting}

\begin{tabular}{lr}
\toprule
{} &    Percent \\
White defendants &            \\
\midrule
FPR              &  23.454301 \\
FNR              &  47.722567 \\
PPV              &  59.133489 \\
NPV              &  71.187500 \\
Prevalence       &  39.364303 \\
\bottomrule
\end{tabular}

\begin{lstlisting}[language=Python,style=source]
metrics_black = compute_metrics(matrix_black,
                                'Black defendants')
metrics_black
\end{lstlisting}

\begin{tabular}{lr}
\toprule
{} &    Percent \\
Black defendants &            \\
\midrule
FPR              &  44.846797 \\
FNR              &  27.985271 \\
PPV              &  62.971481 \\
NPV              &  65.045992 \\
Prevalence       &  51.433983 \\
\bottomrule
\end{tabular}

If we look at the error rates (FPR and FNR), it seems like COMPAS is
biased against black defendants:

\begin{itemize}
\item
  Their false positive rate is higher (45\% vs 23\%): among people who
  \emph{will not} recidivate, black defendants are more likely to be
  classified high risk.
\item
  Their false negative rate is lower (28\% vs 48\%): among people who
  \emph{will} recidivate, black defendants are less likely to be
  classified low risk.
\end{itemize}

But if we look at the the predictive values (PPV and NPV) it seems like
COMPAS is biased in favor of black defendants:

\begin{itemize}
\item
  Among people in the \emph{high risk group}, black defendants are more
  likely to be charged with another crime (63\% vs 59\%).
\item
  Among people in the \emph{low risk group}, black defendants are less
  likely to ``survive'' two years without another charge (65\% vs 71\%).
\end{itemize}

It seems like we should be able to fix these problems, but it turns out
that we can't. We'll see why in the next section.

\hypertarget{what-would-it-take}{%
\section{What Would It Take?}\label{what-would-it-take}}

Suppose we want to fix COMPAS so that predictive values are the same for
black and white defendants. We could do that by using different
thresholds for the two groups.

In this section, we'll figure out what it would take to re-calibrate
COMPAS; then we'll see what effect that would have on predictive values.

The following function loops through possible thresholds, makes the
confusion matrix with each threshold, and computes accuracy metrics.

\begin{lstlisting}[language=Python,style=source]
def sweep_threshold(cp):
    """Sweep a range of threshold and compute accuracy metrics.

    cp: DataFrame of COMPAS data

    returns: DataFrame with one row for each threshold and
             one column for each metric
    """
    index = range(0, 11)
    columns = ['FPR', 'FNR', 'PPV', 'NPV', 'Prevalence']
    table = pd.DataFrame(index=index, columns=columns, dtype=float)

    for threshold in index:
        m = make_matrix(cp, threshold)
        metrics = compute_metrics(m)
        table.loc[threshold] = metrics['Percent']

    return table
\end{lstlisting}

Here's the resulting table for all defendants.

\begin{lstlisting}[language=Python,style=source]
table_all = sweep_threshold(cp)
table_all.head()
\end{lstlisting}

\begin{tabular}{lrrrrr}
\toprule
{} &         FPR &        FNR &        PPV &        NPV &  Prevalence \\
\midrule
0 &  100.000000 &   0.000000 &  45.065151 &        NaN &   45.065151 \\
1 &   71.435781 &   9.474008 &  50.969865 &  78.611111 &   45.065151 \\
2 &   55.084532 &  18.486620 &  54.831368 &  74.758505 &   45.065151 \\
3 &   43.325763 &  27.130114 &  57.978463 &  71.803069 &   45.065151 \\
4 &   32.349230 &  37.403876 &  61.350618 &  68.796510 &   45.065151 \\
\bottomrule
\end{tabular}

The following figure shows error rates as a function of threshold.

\begin{lstlisting}[language=Python,style=source]
table_all['FPR'].plot(color='C2')
table_all['FNR'].plot(color='C4')

decorate(xlabel='Threshold',
         ylabel='Percent',
         title='Error rates for a range of thresholds')
\end{lstlisting}

\begin{center}
\includegraphics[scale=0.75]{02_calibration_files/02_calibration_37_0.pdf}
\end{center}

When the threshold is low, almost everyone is in the high risk group; in
that case:

\begin{itemize}
\item
  FNR is low because most recidivists are in the high risk group, but
\item
  FPR is high because most non-recidivists are \emph{also} in the high
  risk group.
\end{itemize}

When the threshold is high, almost everyone is in the low risk group,
and the metrics are the other way around:

\begin{itemize}
\item
  FPR is low because most non-recidivists are in the low risk group, but
\item
  FNR is high because most recidivists are \emph{also} in the low risk
  group.
\end{itemize}

The following figure shows predictive values for a range of thresholds.

\begin{lstlisting}[language=Python,style=source]
table_all['PPV'].plot(color='C0')
table_all['NPV'].plot(color='C1')

decorate(xlabel='Threshold',
         ylabel='Percent',
         title='Predictive values for a range of thresholds')
\end{lstlisting}

\begin{center}
\includegraphics[scale=0.75]{02_calibration_files/02_calibration_39_0.pdf}
\end{center}

When the threshold is too low, PPV is low. When the threshold is too
high, NPV is low.

Now I'll compute tables for black and white defendants separately.

\begin{lstlisting}[language=Python,style=source]
table_white = sweep_threshold(cp[white])
table_black = sweep_threshold(cp[black])
\end{lstlisting}

I'll use the following function to interpolate columns in the table;
that is, for a given threshold I can compute the corresponding metric.

\begin{lstlisting}[language=Python,style=source]
from scipy.interpolate import interp1d

def interpolate(series, value, **options):
    """Evaluate a function at a value.

    series: Series
    value: number
    options: passed to interp1d (default is linear interp)

    returns: number
    """
    interp = interp1d(series.index, series.values, **options)
    return interp(value)
\end{lstlisting}

The following function goes the other way: it estimates the threshold
where a column passes through a given metric.

\begin{lstlisting}[language=Python,style=source]
def crossing(series, value, **options):
    """Find where a function crosses a value.

    series: Series
    value: number
    options: passed to interp1d (default is linear interp)

    returns: number
    """
    interp = interp1d(series.values, series.index, **options)
    return interp(value)
\end{lstlisting}

We can use \passthrough{\lstinline!crossing!} to calibrate the test for
white defendants; that is, we can compute the threshold that would make
the error rates for white defendants the same as for the general
population.

\begin{lstlisting}[language=Python,style=source]
matrix_all = make_matrix(cp)
fpr, fnr = error_rates(matrix_all)
\end{lstlisting}

\begin{lstlisting}[language=Python,style=source]
crossing(table_white['FPR'], fpr)
\end{lstlisting}

\begin{lstlisting}[style=output]
array(3.23048519)
\end{lstlisting}

\begin{lstlisting}[language=Python,style=source]
crossing(table_white['FNR'], fnr)
\end{lstlisting}

\begin{lstlisting}[style=output]
array(3.11788885)
\end{lstlisting}

With a threshold near 3.2, white defendants would have the same error
rates as the general population. Now let's do the same computation for
black defendants.

\begin{lstlisting}[language=Python,style=source]
crossing(table_black['FPR'], fpr)
\end{lstlisting}

\begin{lstlisting}[style=output]
array(5.20906103)
\end{lstlisting}

\begin{lstlisting}[language=Python,style=source]
crossing(table_black['FNR'], fnr)
\end{lstlisting}

\begin{lstlisting}[style=output]
array(5.01417524)
\end{lstlisting}

To get the same error rates for black and white defendants, we would
need different thresholds: about 5.1 compared to 3.2. At those levels,
the predictive values are substantially different. Here's PPV for each
group with different thresholds:

\begin{lstlisting}[language=Python,style=source]
interpolate(table_white['PPV'], 3.2)
\end{lstlisting}

\begin{lstlisting}[style=output]
array(55.23319482)
\end{lstlisting}

\begin{lstlisting}[language=Python,style=source]
interpolate(table_black['PPV'], 5.1)
\end{lstlisting}

\begin{lstlisting}[style=output]
array(66.21639173)
\end{lstlisting}

With equal error rates, we get different PPV:

\begin{itemize}
\item
  Among white defendants in the high risk group, about 55\% would
  recidivate.
\item
  Among black defendants in the high risk group, about 66\% would
  recidivate.
\end{itemize}

Here's NPV for each group with different thresholds:

\begin{lstlisting}[language=Python,style=source]
interpolate(table_white['NPV'], 3.2)
\end{lstlisting}

\begin{lstlisting}[style=output]
array(73.06639734)
\end{lstlisting}

\begin{lstlisting}[language=Python,style=source]
interpolate(table_black['NPV'], 5.1)
\end{lstlisting}

\begin{lstlisting}[style=output]
array(62.16782561)
\end{lstlisting}

With equal error rates, the NPVs are substantially different:

\begin{itemize}
\item
  Among white defendants in the low risk group, 73\% survive two years
  without another charge.
\item
  Among black defendants in the low risk group, 62\% survive.
\end{itemize}

To summarize, if the test is calibrated in terms of error rates, it is
not calibrated in terms of predictive values.

\begin{itemize}
\item
  If we make the error rates more equal, we make the predictive values
  more unfair, and
\item
  If we make the predictive values more equal, we make the error rates
  more unfair.
\end{itemize}

Fundamentally, the problem is that the prevalence of recidivism is
different in the two groups: about 39\% of white defendants were charged
with another crime within two years, compared to 51\% of black
defendants.

As long as that's the case (for any two groups) the predictive values
and error rates can't be ``fair'' at the same time.

\hypertarget{roc}{%
\section{ROC}\label{roc}}

In the previous section I plotted various metrics as as function of
threshold. Another common and useful way to visualize these results is
to plot sensitivity (which is the complement of FNR) versus FPR. For
historical reasons, the result is called a receiver operating
characteristic (ROC) curve (see
\url{https://en.wikipedia.org/wiki/Receiver_operating_characteristic}).

The following function plots the ROC curve:

\begin{lstlisting}[language=Python,style=source]
def plot_roc(table, **options):
    """Plot the ROC curve.

    table: DataFrame of metrics as a function of
           classification threshold
    options: passed to plot
    """
    plt.plot([0,100], [0,100], ':', color='gray')
    sens = 100-table['FNR']
    plt.plot(table['FPR'], sens, **options)
    decorate(xlabel='FPR',
             ylabel='Sensitivity (1-FNR)',
             title='ROC curve')
\end{lstlisting}

Here's the ROC curve for all defendants.

\begin{lstlisting}[language=Python,style=source]
plot_roc(table_all, color='C2', label='All defendants')
\end{lstlisting}

\begin{center}
\includegraphics[scale=0.75]{02_calibration_files/02_calibration_64_0.pdf}
\end{center}

The green line is the ROC curve. The gray dotted line shows the identity
line for comparison.

An ideal test would have high sensitivity for all values of FPR, but in
reality there is almost always a trade-off:

\begin{itemize}
\item
  When FPR is low, sensitivity is low.
\item
  In order to get more sensitivity, we have to accept a higher FPR.
\end{itemize}

The ROC curve tells us how much sensitivity we get for a given FPR or,
the other way around, how much FPR we have to accept to achieve a given
sensitivity. The following figure shows the ROC curves for white and
black defendants.

\begin{lstlisting}[language=Python,style=source]
plot_roc(table_white)
plot_roc(table_black)
\end{lstlisting}

\begin{center}
\includegraphics[scale=0.75]{02_calibration_files/02_calibration_66_0.pdf}
\end{center}

The ROC curves are similar for the two groups, which shows that we can
achieve nearly the same error rates (FPR and FNR) for the two groups, as
we did in the previous section. It also shows that the test has nearly
the same ``concordance'' for both groups, which I explain in the next
section.

\hypertarget{auc}{%
\section{AUC}\label{auc}}

The authors of the ProPublica article published a supplementary article,
``How We Analyzed the COMPAS Recidivism Algorithm'', which describes
their analysis in more detail (see
\url{https://www.propublica.org/article/how-we-analyzed-the-compas-recidivism-algorithm}).

As another metric of accuracy, they estimate \textbf{concordance}, which
they describe like this:

\begin{quote}
Overall, {[}COMPAS has{]} a concordance score of 63.6 percent. That
means for any randomly selected pair of defendants in the sample, the
COMPAS system can accurately rank their recidivism risk 63.6 percent of
the time (e.g.~if one person of the pair recidivates, that pair will
count as a successful match if that person also had a higher score). In
its study, Northpointe reported a slightly higher concordance: 68
percent.
\end{quote}

They explain:

\begin{quote}
{[}These estimates{]} are lower than what Northpointe describes as a
threshold for reliability. ``A rule of thumb according to several recent
articles is that AUCs of .70 or above typically indicate satisfactory
predictive accuracy, and measures between .60 and .70 suggest low to
moderate predictive accuracy,'' the company says in its study.
\end{quote}

There are several ways to compute concordance, but one of the simplest
is to compute the area under the ROC curve. If you would like to know
why this works, you might find this discussion helpful:
\url{https://stats.stackexchange.com/questions/180638/how-to-derive-the-probabilistic-interpretation-of-the-auc}.

Since we've already computed the ROC, we can use Simpson's rule to
estimate the area under the curve (see
\url{https://en.wikipedia.org/wiki/Simpsons_rule}).

\begin{lstlisting}[language=Python,style=source]
from scipy.integrate import simps

def compute_auc(table):
    """Compute the area under the ROC curve.

    Uses the trapezoid rule, so
    """
    y = 100-table['FNR']
    x = table['FPR']
    y = y.sort_index(ascending=False) / 100
    x = x.sort_index(ascending=False) / 100
    return simps(y.values, x.values)
\end{lstlisting}

The concordance (AUC) for all respondents is about 70\%.

\begin{lstlisting}[language=Python,style=source]
compute_auc(table_all)
\end{lstlisting}

\begin{lstlisting}[style=output]
0.7059974460900778
\end{lstlisting}

For the subgroups it is slightly lower, but also near 70\%.

\begin{lstlisting}[language=Python,style=source]
compute_auc(table_white)
\end{lstlisting}

\begin{lstlisting}[style=output]
0.6995093159638619
\end{lstlisting}

\begin{lstlisting}[language=Python,style=source]
compute_auc(table_black)
\end{lstlisting}

\begin{lstlisting}[style=output]
0.694567757058852
\end{lstlisting}

Different ways of computing concordance handle ties differently, which
is probably why we, ProPublica, and Northpointe get somewhat different
estimates. But qualitatively they all tell the same story; as a binary
classifier, COMPAS is only moderately accurate. However, it seems to be
equally accurate, by this metric, for white and black defendants.

\hypertarget{summary}{%
\section{Summary}\label{summary}}

In this chapter, we replicated the analysis reported in the WaPo article
and confirmed two of the arguments they presented:

\begin{enumerate}
\def\labelenumi{\arabic{enumi}.}
\item
  COMPAS is calibrated in the sense that white and black defendants with
  the same risk score have almost the same probability of being charged
  with another crime. This implies that it has roughly the same
  predictive value for both groups.
\item
  It is impossible for COMPAS to have the same predictive values for
  both groups and the same error rates at the same time.
\end{enumerate}

And we showed:

\begin{itemize}
\item
  If you design a test to achieve equal predictive value across groups
  with different prevalence, you will find that error rates differ.
  Specifically, false positive rates will be higher in groups with
  higher recividism.
\item
  If you design a test to achieve equal error rates across groups, you
  will find that predictive values differ. Specifically, positive
  predictive value will be lower in groups with lower rates of
  recidivism.
\end{itemize}

Finally, we derived the ROC curve and computed AUC, which shows that
COMPAS has nearly the same concordance for white and black defendants.


\documentclass{article}
\usepackage{geometry}
\usepackage[utf8]{inputenc}
\usepackage{amssymb}
\usepackage{amsmath}
\usepackage{url}

\newcommand{\reals}{\mathbb{R}}
\newcommand{\normal}{\mathcal{N}}
\newcommand{\pathx}{x}
\newcommand{\pathy}{y}
\newcommand{\measx}{\tilde{x}}
\newcommand{\measy}{\tilde{y}}

\title{Detailed balance for Gen's \texttt{general\_mh} operator}
\author{Marco Cusumano-Towner}

\begin{document}

\maketitle

\section{Discrete Random Choices Only}
This section shows that Gen's \texttt{general\_mh} operator satisfies detailed balance, given that its requirements are satisfied, and given that only discrete random choices are made.

\paragraph{Requirements for \texttt{general\_mh}}
Let $p(t; x)$ denote the distribution on assignments $t$ of the model generative function, parametrized by arguments $x \in X$.
Let $q(u; t, x, y)$ denote the distribution on assignments $u$ of the proposal generative function, parametrized by a model assignment $t$, model arguments $x$, and proposal arguments $y \in Y$.
A proposal distribution must be defined for all $(x, y, t)$ such that $x \in X$, $y \in Y$, and $p(t; x) > 0$.
For some $x \in X$ and $y \in Y$, let $Z_{x,y} = \{(t, u) : p(t; x) > 0, q(u; t, x, y) > 0\}$.
We also require a bijection $f_{x,y} : Z_{x,y} \to Z_{x,y}$ such that $f^{-1}_{x,y} = f_{x,y}$ (i.e. $f_{x,y}$ is its own inverse or an `involution').
Let $f_{x,y}(t, u) = (f^T_{x,y}(t, u), f^U_{x,y}(t, u))$.

\paragraph{The \texttt{general\_mh} procedure}
The \texttt{general\_mh} operator takes a $x \in X$, $y \in Y$, and $t$ such that $p(t; x) > 0$, and samples $u \sim q(\cdot; t, x, y)$.
Then, it applies the bijection to obtain $(t', u') = f_{x,y}(t, u)$.
Then, it computes the following acceptance probability:
\[
\alpha(x, y, t, u) = \min\left\{ 1, \frac{p(t'; x) q(u'; t', x, y)}{p(t; x) q(u; t, x, y)} \right\}
\]
With probability $\alpha(x, y, t, u)$ it returns a trace containing the new assignment $t'$ and otherwise it returns a trace containing the original assignment $t$.
Let $k(t'; t, x, y)$ denote the distribution on return value assignments of the procedure given inputs $x, y, t$, given by:
\begin{align}
    k(t'; t, x, y)
    &= \sum_{u} q(u; t, x, y) \left( \delta(f^T_{x,y}(t, u), t') \alpha(x, y, t, u) + (1 - \alpha(x, y, t, u)) \delta(t, t') \right)\\
    &= \sum_{u : f^T_{x,y}(t, u) = t'} q(u; t, x, y) \alpha(x, y, t, u) + \delta(t, t') \sum_u q(u; t, x, y) (1 - \alpha(x, y, t, u))
\end{align}
where $\delta$ is the Kronecker delta.

\paragraph{Detailed balance}
We now show that for all $x \in X$ and $y \in Y$, and for all $t$ such that $p(t; x) > 0$ and all $t'$ such that $p(t'; x) > 0$:
\begin{equation} \label{eq:db}
p(t; x) k(t'; t, x, y) = p(t'; x) k(t;, t', x, y)
\end{equation}
First, consider the terms on both sides of Equation~(\ref{eq:db}) that are associated with acceptance:
\begin{align}
p(t; x) \sum_{u : f^T_{x,y}(t, u) = t'} q(u; t, x, y) \alpha(x, y, t, u) &= p(t'; x) \sum_{u' : f^T_{x,y}(t', u') = t} q(u'; t', x, y) \alpha(x, y, t', u')
\end{align}
To show equality, establish a one-to-one correspondence between the sets $\{u : f^T_{x,y}(t, u) = t'\}$ and $\{u' : f^T_{x,y}(t', u') = t\}$ that index the sums, given by $u' = g_{x,y,t,t'}(u) = f^U_{x,y}(t, u)$, and $g_{x,y,t,t'}^{-1}(u') = f_{x,y}^U(t', u')$.
That $g_{x,y,t,t'}$ is a bijection follows from the fact that $f_{x,y}$ is a bijection.
For each such pair $(u, u')$, it suffices to show:
\begin{align}
p(t; x) q(u; t, x, y) \alpha(x, y, t, u) &= p(t'; x) q(u'; t', x, y) \alpha(x, y, t', u')
\end{align}
It suffices to show that:
\begin{align}
    \frac{\alpha(x, y, t, u)}{\alpha(x, y, t', u')} = \frac{p(t'; x) q(u'; t', x, y)}{p(t; x) q(u; t, x, y)}
\end{align}
This can be shown by considering two cases: Either $\alpha(x, y, t, u) \ge 1$ in which case $\alpha(x, y, t', u') \le 1$, or $\alpha(x, y, t', u') > 1$ in which case $\alpha(x, y, t', u') < 1$.
Next, consider the terms on both sides of Equation~(\ref{eq:db}) that are associated with rejection:
\begin{align}
    \delta(t, t') \sum_u q(u; t, x, y) (1 - \alpha(x, y, t, u)) = \delta(t', t) \sum_{u'} q(u'; t', x, y) (1 - \alpha(x, y, t', u'))
\end{align}
If $t \ne t'$ then we have $\delta(t, t') = \delta(t', t) = 0$ and we are done.
If $t = t'$ then renaming $u'$ to $u$ on the right-hand side gives the equivalance.

\section{Including Continuous Random Choices}
To extend \texttt{general\_mh} to handle continuous random choices, we need to require further structure on the involution $f_{x,y}$.
In particular, we require that $f_{x,y}$ can be decomposed into (i) an involution $f_{x,y,\mathrm{disc}} = f_{x,y,\mathrm{disc}}^{-1}$ on the discrete random choices, and (ii) a family of diffeomorphisms on the continuous random choices, indexed by assignments to the discrete random choices.
For any value $d$ of the discrete random choices, we require a bijection $f_{x,y,\mathrm{cont},d}$ on the such that $f^{-1}_{x,y,\mathrm{cont},d}$ = $f_{x,y,\mathrm{cont},f_{x,y,\mathrm{disc}}(d)}$.
Then, the involution $(d', r') = f_{x,y}(d, r)$ where $d, d'$ are the previous and new assignments to the discrete-valued choices, and $r, r'$ are the previous and new assignments to the continuous random choices, is constructed by first evaluating $d' = f_{x,y,\mathrm{disc}}(d)$ and then by evaluating $r' = f_{x,y,\mathrm{cont},d}(r)$.
The log-determinant of the Jacobian matrix of $f_{x,y,\mathrm{cont},d}$ is evaluated at $r$ and added to the log acceptance ratio.

\end{document}


\documentclass{ximera}
\input{../preamble}
\title{Trigonometric Integrals}
%%%%%\author{Philip T. Gressman}

\begin{document}
\begin{abstract}
We learn various techniques for integrating certain combinations of trigonometric functions.
\end{abstract}
\maketitle

\section*{(Video) Calculus: Single Variable}
\youtube{Ltm_XPDXea8}

\section*{Online Texts}
\begin{itemize}
\item \link[OpenStax II 3.2: Trigonometric Integrals]{https://openstax.org/books/calculus-volume-2/pages/3-2-trigonometric-integrals}
\item \link[Ximera OSU: Trigonometric Integrals]{https://ximera.osu.edu/mooculus/calculus2/trigonometricIntegrals/titlePage}
\item \link[Community Calculus 8.2: Powers of Sine and Cosine]{https://www.whitman.edu/mathematics/calculus_online/section08.02.html}
\end{itemize}

\section*{Examples}

\begin{example}
Compute the indefinite integrals
\[ \int \cos^5 3x \sin^2 3x \, dx \ \text{ and } \ \ \int \cos^2 3x \sin^5 3x \, dx. \]
\begin{itemize}
\item When dealing with products of sines and cosines of the same quantity (in this case, the $3x$ is the same inside both the sine and the cosine), we can use a substitution. We look for one with an odd power and build a substitution using the other.   In this case, we would use the substitution \wordChoice{\choice{$u = \cos 3x$}\choice[correct]{$u = \sin 3x$}} in the first integral and \wordChoice{\choice[correct]{$u = \cos 3x$}\choice{$u = \sin 3x$}} in the second.
\item Using the substitutions just identified, we have $du = \answer{3 \cos 3x} \, dx$ in the former case and $du = \answer{-3 \sin 3x}\, dx$ in the latter. This means the integrals become
\[ \frac{1}{3} \int \cos^4 3x \sin^2 3x \, du \ \ \text{ and } \ \ - \frac{1}{3} \int \cos^2 3x \sin^4 3x \, du. \]
\item We continue to simplify, using the trig identity $\cos^2 \theta + \sin^2 \theta = 1$ to completely eliminate all references to the variable $x$ in the integrand:
\[ \frac{1}{3} \int (\answer{1-u^2})^2 u^2 \, du \ \ \text{ and } \ \ - \frac{1}{3} \int u^2 (\answer{1-u^2})^2 \, du. \]
\item Now we calculate the integral, giving
\[ \frac{1}{3} \int (\answer{1-u^2})^2 u^2 \, du = \answer{\frac{u^3}{9} - \frac{2 u^5}{15} + \frac{u^7}{21}} + C \]
in the first case and
\[ -\frac{1}{3} \int u^2 (\answer{1-u^2})^2 \, du = \answer{-\frac{u^3}{9} + \frac{2 u^5}{15} - \frac{u^7}{21}} + C \]
in the second.
\item To conclude, we reverse the substitution, so that
\[  \int \cos^5 3x \sin^2 3x \, dx = \answer{\frac{(\sin 3x)^3}{9} - \frac{2 (\sin 3x)^5}{15} + \frac{(\sin 3x)^7}{21}} + C \]
and
\[ \int \cos^2 3x \sin^5 3x \, dx = \answer{-\frac{(\cos 3x)^3}{9} + \frac{2 (\cos 3x)^5}{15} - \frac{(\cos 3x)^7}{21}} + C. \]
\end{itemize}
\end{example}

\begin{example}
Compute the indefinite integral
\[ \int \sin^2 3x \cos^2 3x \, dx. \]
\begin{itemize}
\item When both powers are even, your only option is to use a trigonometric identity to reduce the power. In this case, the identities are
\[ \sin^2 \theta = \frac{1 - \cos 2 \theta}{2}  \ \ \text{ and } \ \ \cos^2 \theta = \frac{1 + \cos 2 \theta}{2}. \]
\item
This means that
\[ \sin^2 3x \cos^2 3 x = \frac{1}{4} - \answer{ \frac{(\cos 6 x)^2}{4}}. \]
\item
Because we still have only even powers, we should use power reduction again:
\[ \sin^2 3x \cos^2 3x = \frac{1}{4} - \frac{1}{4} \left[ \frac{1}{2} + \answer{\frac{1}{2} \cos 12x} \right] = \frac{1}{8} - \frac{1}{8} \answer{\cos 12x}. \]
\item
Integrating this last expression gives
\[ \int \sin^2 3x \cos^2 3x \, dx = \answer{\frac{x}{8} - \frac{1}{96} \sin 12x} + C. \]
\end{itemize}
\end{example}

\begin{example}
Compute the indefinite integrals
\[ \int \sec^2 3x \tan^2 3x \, dx \ \ \text{ and } \ \ \int \sec^3 3x \tan^3 3x \, dx. \]
\begin{itemize}
\item In this case we look for either an even power of $secant$, which indicates a tangent substitution, or an odd number of both secant and tangent, which indicates a secant substitution. So we substitute $u = \tan 3x$ in the first integral and $u = \sec 3x$ in the second. To simplify and write the integrands in terms of $u$ only, use the identity $\sec^2 \theta = \tan^2 \theta + 1$.  This gives
\[ \int \answer{\frac{1}{3} u^2} \, du \ \ \text{ and } \ \ \int \answer{\frac{1}{3} u^2 (u^2 - 1)} \, du \]
for the two integrals (don't forget the extra factor of $1/3$ coming from the chain rule).
\item Integrating and reversing the substitution gives
\[ \int \sec^2 3x \tan^2 3x \, dx = \answer{ \frac{(\tan 3x)^3}{9}} + C \]
and
\[ \int \sec^3 3x \tan^3 3x \, dx = \answer{ \frac{(\sec 3x)^5}{15} - \frac{(\sec 3x)^3}{9}} + C. \]
\end{itemize}
\end{example}

\begin{example}
When there are are odd powers of secant and even (or just zero) powers of tangent, there's a trick: integrate by parts letting $dv = \sec^2 x$ and $u$ being everything else. \label{trig:reduce_example}
\[ \begin{aligned}
\int \sec^7 x \, dx & = \int \sec^{\answer{5}} x  \sec^2 x \, dx \\
& = \sec^5 x \answer{\tan x} - \int \answer{5 (\sec x)^4 \sec x (\tan x)^2} dx \\
& = \sec^5 x \answer{\tan x} - 5 \int \sec^7 x \, dx + 5 \int \sec^5 x \, dx.
\end{aligned} \]
Just like for other integration-by-parts examples, we can now \textit{solve} for the integral in terms of a simpler integral:
\[ \int \sec^7 x \, dx = \answer{\frac{1}{6}} \left[ \answer{(\sec x)^5 \tan x} + 5 \int \sec^5 x \, dx \right]. \]
This is an example of a \textit{reduction formula}, because the integral on the right-hand side is similar to the one we started with, but simpler. We could then compute the integral of $\sec^5 x$ in terms of the integral of $\sec^3 x$ and ultimately to $\sec x$, which is one which we can evaluate (or look up in a table).
\end{example}

\end{document}


\clearpage
\subsection{Scalar SM4 Acceleration}
\label{sec:scalar:sm4}

\medskip

\begin{bytefield}[bitwidth={1.05em},endianness={big}]{32}
\bitheader{0-31} \\
\encsmfoured
\encsmfourks
\end{bytefield}

\begin{cryptoisa}
RV32 / RV64:
    sm4ed     rt, rs2, bs
    sm4ks     rt, rs2, bs
\end{cryptoisa}

This section proposes acceleration instructions for
the SM4 block cipher\cite{block:sm4:1, ietf:sm4}.

The instructions are taken from proposals found in \cite{MJS:LWAES:20}.
They are very lightweight and require only a single SBox instance.
They are designed to give a very high performance improvement with
minimal area requirements, and resemble a TTables-esq
software implementation.

\begin{itemize}
\item \mnemonic{sm4ed} - Encrypt/Decrypt. Applies the
    SBox and $L$ transformations as part of the round function.
\item \mnemonic{sm4ks} - KeySchedule. Applies the
    SBox and $L'$ transformations as part of the KeySchedule.
\end{itemize}

RISC-V Sail model code for each instruction is found in figure
\ref{fig:sail:sm4}.
Note that the instructions source their destination register from
bits $19:15$ of the encoding, rather than the usual $11:7$.
This is because the instructions are designed to be used such that
the destination register is always the same as {\tt rs1}.
See Appendix \ref{sec:scalar:encodings} for more information.

%
% Old pseudo code for SM4.
%
%\begin{figure}[h]
%\begin{lstlisting}[language=pseudo]
%ssm4.ed(rs1, rs2, bs):
%    x.8   = rs2.8[bs]
%    x.32  = zext(SM4SBox(x.8), 32)
%    x.32  = x.32 ^ (x.32 << 8) ^ (x.32 << 2) ^ (x.32 << 18) ^
%                   ((x.32 & 0x3F) << 26) ^ ((x.32 & 0xC0) << 10)
%    x.32  = ROTL(x.32, 8*bs)
%    rd    = x.32 ^ rs1
%
%ssm4.ks(rs1, rs2, bs):
%    x.8   = rs2.8[bs]
%    x.32  = zext(SM4SBox(x.8), 32)
%    x.32  = x.32 ^ ((x.32 & 0x07) << 29) ^ ((x.32 & 0xFE) << 7) ^
%                   ((x.32 & 1) << 23) ^ ((x.32 & 0xF8) << 13)
%    x.32  = ROTL(x.32, 8*bs)
%    rd    = x.32 ^ rs1
%\end{lstlisting}
%\caption{Scalar SM4 instruction pseudocode.}
%\end{figure}

\begin{figure}[h]
\lstinputlisting[language=sail,firstline=142,lastline=165]{../extern/sail-riscv/model/riscv_insts_kext.sail}
\caption{RISC-V Sail model specification for the SM4 instructions.}
\label{fig:sail:sm4}
\end{figure}


\subsection{Introduction}
The AES (Advanced Encryption Standard), also known by its original name Rijndael  is a specification for the encryption of electronic data established by the U.S. National Institute of Standards and Technology (NIST) in 2001. AES is a subset of the Rijndael block cipher developed by two Belgian cryptographers, Vincent Rijmen and Joan Daemen, who submitted a proposal to NIST during the AES selection process. Rijndael is a family of ciphers with different key and block sizes.

\subsection{Properties}
It is one of the symmetric key block cipher technique \textit{i.e.} same key is used to encrypt an decrypt. It takes 128 bit message block at a time and 128 bit (or 192 bit or 256 bit) key block.

AES is based on a design principle known as a substitution-permutation network, and is efficient in both software and hardware. Unlike its predecessor DES, AES does not use a Feistel network. AES operates on a $4 \times 4$ column-major order array of bytes (1 byte = 8 bits), termed the state. Most AES calculations are done in a particular finite field.

For instance, if there are 16 bytes these bytes are represented as this two-dimensional array (state matrix) \\
$$
\begin{bmatrix}
b_0 && b_4 && b_8 && b_C \\
b_1 && b_5 && b_9 && b_D \\
b_2 && b_6 && b_A && b_E \\
b_3 && b_7 && b_B && b_F
\end{bmatrix}
$$

The key size used for an AES cipher specifies the number of transformation rounds that convert the input, called the plaintext, into the final output, called the ciphertext. The number of rounds are as follows:
\begin{itemize}
\item 10 rounds for 128-bit keys.
\item 12 rounds for 192-bit keys.
\item 14 rounds for 256-bit keys.
\end{itemize}

Each round consists of several processing steps, including one that depends on the encryption key itself. A set of reverse rounds are applied to transform ciphertext back into the original plaintext using the same encryption key.

All the calculation of AES can be calculated using either Galois Field $GF(2^8)$ and Euclidean algebra (takes more time but less space) or pre-calculated table driven way (takes less time but more space).

\subsection{Algorithm}
\subsubsection{Message Division}
Divide the message by 128 bits chunks of state matrices

\subsubsection{Key Expansion}
Round keys are derived from the cipher key using Rijndael's key schedule. AES requires a separate 128-bit round key block for each round plus one more.

\subsubsection{Initial Step}
For each message block: \\
\algoTab $ K_{ini} \gets genRoundKey(0, K_{main}) $ \\
\algoTab $ M_0 \gets addRoundKey(M_{main}, K_{ini}) $ \\

\subsubsection{Rounds}
\algoTab for each round $ 0 \leq i < (totalRounds - 1) $ :\\
\algoTab \algoTab $ M_i \gets subBytes(M_i) $ \\
\algoTab \algoTab $ M_i \gets shiftRows(M_i) $ \\
\algoTab \algoTab $ M_i \gets mixColumns(M_i) $ \\
\algoTab \algoTab $ K_i \gets genRoundKey(i, K_{main}) $ \\
\algoTab \algoTab $ M_i \gets addRoundKey(M_i, K_i) $ \\

\subsubsection{Final Step}
It is $ i = (totalRounds - 1)^{th} $ round;\\ No column mixing here or it will get back close to original message block. \\
\algoTab \algoTab $ M_i \gets subBytes(M_i) $ \\
\algoTab \algoTab $ M_i \gets shiftRows(M_i) $ \\
\algoTab \algoTab $ K_{fin} \gets genRoundKey(i, K_{main}) $ \\
\algoTab \algoTab $ S_{fin} \gets addRoundKey(M_i, K_{fin}) $ \\

\subsubsection{Used Functions}
\textbf{subBytes(state) :: state} \\
In the SubBytes step, each byte in the state array is replaced with a SubByte $S(a_{i,j})$ using an 8-bit substitution box. This operation provides the \textit{non-linearity} in the cipher. The S-box used is derived from the multiplicative inverse over $GF(2^8)$, known to have good non-linearity properties. To avoid attacks based on simple algebraic properties, the S-box is constructed by combining the inverse function with an invertible affine transformation. The S-box is also chosen to avoid any fixed points (and so is a derangement), i.e. $ S(b_{i, j}) \neq b_{i, j} $ and also any opposite fixed points, i.e. $ S(b_{i, j}) \oplus b_{i, j} \neq FF_{16} $. While performing the decryption, the InvSubBytes step (the inverse of SubBytes) is used, which requires first taking the inverse of the affine transformation and then finding the multiplicative inverse.
Returns:
$$
\begin{bmatrix}
S(b_0) && S(b_4) && S(b_8) && S(b_C) \\
S(b_1) && S(b_5) && S(b_9) && S(b_D) \\
S(b_2) && S(b_6) && S(b_A) && S(b_E) \\
S(b_3) && S(b_7) && S(b_B) && S(b_F)
\end{bmatrix}
$$
\textbf{shiftRows(state) :: state} \\
The ShiftRows step operates on the rows of the state; it cyclically left shifts the bytes in each row by a certain offset which is equal to Zero initiated row number \textit{i.e.} in the row number set \{0, 1, 2, 3\}. It provides \textit{shuffling} to avoid the columns being encrypted independently.
Returns:
$$
\begin{bmatrix}
b_0 && b_4 && b_8 && b_C \\
b_5 && b_9 && b_D && b_1 \\
b_A && b_E && b_2 && b_6 \\
b_F && b_3 && b_7 && b_B
\end{bmatrix}
$$
\textbf{mixColumns(state) :: state} \\
In the MixColumns step, the four bytes of each column of the state are combined using an invertible linear transformation. The MixColumns function takes four bytes as input and outputs four bytes, where each input byte affects all four output bytes. Together with ShiftRows, MixColumns provides diffusion in the cipher.
During this operation, each column is transformed using a fixed matrix (matrix left-multiplied by column gives new value of column in the state):
Returns:
$$
\begin{bmatrix}
FF_{16} && FF_{16} && FF_{16} && FF_{16} \\
FF_{16} && FF_{16} && FF_{16} && FF_{16} \\
FF_{16} && FF_{16} && FF_{16} && FF_{16} \\
FF_{16} && FF_{16} && FF_{16} && FF_{16}
\end{bmatrix}
\oplus
\begin{bmatrix}
b_0 && b_4 && b_8 && b_C \\
b_5 && b_9 && b_D && b_1 \\
b_A && b_E && b_2 && b_6 \\
b_F && b_3 && b_7 && b_B
\end{bmatrix}
\times
\begin{bmatrix}
2 && 3 && 1 && 1 \\
1 && 2 && 3 && 1 \\
1 && 1 && 2 && 3 \\
3 && 1 && 1 && 2
\end{bmatrix}
$$
\textbf{genRoundKey(round, state) :: state} \\
AES (Rijndael) uses a key schedule to expand a short key into a number of separate round keys. This is known as the Rijndael key schedule. The three AES variants have a different number of rounds. Each variant requires a separate 128-bit round key for each round plus one more. The key schedule produces the needed round keys from the initial key.

Each round has a round constant $ rcon_i $ which is calculated by,
$$
rcon_i =
\begin{bmatrix}
rc_i && 00_{16} && 00_{16} && 00_{16}
\end{bmatrix}
$$
where,
$$
rc_i =
\begin{cases}
1, & \text{if} (i = 1) \\
2 \times rc_{i-1}, & \text{if} (i > 1) \text{and} (rc_{i-1} < 80_{16}) \\
(2 \times rc_{i-1}) \oplus 1B_{16}, & \text{if} (i > 1) \text{and} (rc_{i-1} > 80_{16})
\end{cases}
$$

Two main functions used are,
$$
RotWord(
\begin{bmatrix}
b_0 && b_1 && b_2 && b_3
\end{bmatrix}
) =
\begin{bmatrix}
b_1 && b_2 && b_3 && b_0
\end{bmatrix}
$$
and
$$
SubWord(
\begin{bmatrix}
b_0 && b_1 && b_2 && b_3
\end{bmatrix}
) =
\begin{bmatrix}
S(b_1) && S(b_2) && S(b_3) && S(b_0)
\end{bmatrix}
$$

For each of $ 4 \times r + 1 $ rounds,
$$
W_i =
\begin{cases}
K_i, & \text{if} (i < n) \\
W_{i-n} \oplus SubWord(RotWord(W_{i-1})) \oplus rcon_{i/n}, & \text{if} (i \geq n) and \text{and} (i \equiv 0 \mod n) \\
W_{i-n} \oplus SubWord(W_{i-1}), & \text{if} (i \geq n) \text{, } (n > 6) and \text{and} (i \equiv 4 \mod n) \\
W_{i-n} \oplus W_{i-1}, & \text{otherwise}
\end{cases}
$$

\textbf{addRoundKey(state, state) :: state} \\
In the AddRoundKey step, the subkey is combined with the state. For each round, a subkey is derived from the main key using Rijndael's key schedule; each subkey is the same size as the state. The subkey is added by combining each byte of the state with the corresponding byte of the subkey using bitwise XOR.
Returns:
$$
\begin{bmatrix}
m_0 && m_4 && m_8 && m_C \\
m_5 && m_9 && m_D && m_1 \\
m_A && m_E && m_2 && m_6 \\
m_F && m_3 && m_7 && m_B
\end{bmatrix}
\oplus
\begin{bmatrix}
k_0 && k_4 && k_8 && k_C \\
k_5 && k_9 && k_D && k_1 \\
k_A && k_E && k_2 && k_6 \\
k_F && k_3 && k_7 && k_B
\end{bmatrix}
$$

\subsubsection{Message Generation}
After calculating the cipher-text the bytes are converted to consecutive readable strings of characters.
\subsubsection{Decryption}
The decryption is the reverse processing with the ciphertext state blocks with the same key. The reverse operations for each functions are,
\begin{itemize}
\item $ rev(subBytes(state)) \implies invSubBytes(state)$
\item $ rev(shiftRows(state)) \implies invShiftRows(state) or shiftRows(state, right) $
\item $ rev(mixColumns(state)) \text{'s mixing matrix changes to it's inverse matrix} $
\item $ rev(genRoundKey(round, state)) \implies genRoundKey(totalRound - round, state) $
\item $ rev(addRoundKey(state, state)) \text{remains same as if} \{m \oplus k = c\} \text{then} \{c \oplus k = m\} $
\end{itemize}

\subsection{Application}
AES is implemented in secure file transfer protocols like FTPS, HTTPS, SFTP, AS2, WebDAVS, and OFTP.

\subsection{Citing}
Well known real paper ~\cite{rijndael_aes} describes a lot along with we took help from wikipedia ~\cite{wiki_aes}.


\title{Classes of Inference}

{{navbar}}

\subsubsection{Classes of Inference}

Inference is broadly classified under three classes: variational
inference, Monte Carlo, and exact inference.
We highlight how to use inference algorithms from each class.

As an example, we assume a mixture model with latent mixture
assignments \texttt{z}, latent cluster means \texttt{beta}, and
observations \texttt{x}:
\begin{equation*}
p(\mathbf{x}, \mathbf{z}, \beta)
=
\text{Normal}(\mathbf{x} \mid \beta_{\mathbf{z}}, \mathbf{I})
~
\text{Categorical}(\mathbf{z}\mid \pi)
~
\text{Normal}(\beta\mid \mathbf{0}, \mathbf{I}).
\end{equation*}

\subsubsection{Variational Inference}

In variational inference, the idea is to posit a family of approximating
distributions and to find the closest member in the family to the
posterior \citep{jordan1999introduction}.
We write an approximating family,
\begin{align*}
q(\beta;\mu,\sigma) &= \text{Normal}(\beta; \mu,\sigma), \\[1.5ex]
q(\mathbf{z};\pi) &= \text{Categorical}(\mathbf{z};\pi),
\end{align*}
using TensorFlow variables to represent its parameters
$\lambda=\{\pi,\mu,\sigma\}$.
\begin{lstlisting}[language=Python]
from edward.models import Categorical, Normal

qbeta = Normal(loc=tf.Variable(tf.zeros([K, D])),
               scale=tf.exp(tf.Variable(tf.zeros[K, D])))
qz = Categorical(logits=tf.Variable(tf.zeros[N, K]))

inference = ed.VariationalInference({beta: qbeta, z: qz}, data={x: x_train})
\end{lstlisting}
Given an objective function, variational inference optimizes the
family with respect to \texttt{tf.Variable}s.

Specific variational inference algorithms inherit from
the \texttt{VariationalInference} class to define their own methods, such as a
loss function and gradient.
For example, we represent
MAP
estimation with an approximating family (\texttt{qbeta} and
\texttt{qz}) of \texttt{PointMass} random variables, i.e., with all
probability mass concentrated at a point.
\begin{lstlisting}[language=Python]
from edward.models import PointMass

qbeta = PointMass(params=tf.Variable(tf.zeros([K, D])))
qz = PointMass(params=tf.Variable(tf.zeros(N)))

inference = ed.MAP({beta: qbeta, z: qz}, data={x: x_train})
\end{lstlisting}
\texttt{MAP} inherits from \texttt{VariationalInference} and defines a
loss function and update rules; it uses existing optimizers inside
TensorFlow.

\subsubsection{Monte Carlo}

Monte Carlo approximates the posterior using samples
\citep{robert1999monte}. Monte Carlo is an inference where the
approximating family is an empirical distribution,
\begin{align*}
q(\beta; \{\beta^{(t)}\})
&= \frac{1}{T}\sum_{t=1}^T \delta(\beta, \beta^{(t)}), \\[1.5ex]
q(\mathbf{z}; \{\mathbf{z}^{(t)}\})
&= \frac{1}{T}\sum_{t=1}^T \delta(\mathbf{z}, \mathbf{z}^{(t)}).
\end{align*}
The parameters are $\lambda=\{\beta^{(t)},\mathbf{z}^{(t)}\}$.
\begin{lstlisting}[language=Python]
from edward.models import Empirical

T = 10000  # number of samples
qbeta = Empirical(params=tf.Variable(tf.zeros([T, K, D]))
qz = Empirical(params=tf.Variable(tf.zeros([T, N]))

inference = ed.MonteCarlo({beta: qbeta, z: qz}, data={x: x_train})
\end{lstlisting}
Monte Carlo algorithms proceed by updating one sample
$\beta^{(t)},\mathbf{(z)}^{(t)}$ at a time in the empirical approximation.
%
Markov chain Monte Carlo does this sequentially to update
the current sample (index $t$ of \texttt{tf.Variable}s) conditional on
the last sample (index $t-1$ of \texttt{tf.Variable}s).
%
Specific Monte Carlo samplers determine the update rules;
they can use gradients such as in Hamiltonian Monte Carlo
\citep{neal2011mcmc} and graph
structure such as in sequential Monte Carlo \citep{doucet2001introduction}.

\subsubsection{Non-Bayesian Methods}

As a library for probabilistic modeling (not necessarily Bayesian
modeling), Edward is agnostic to the paradigm for inference.  This
means Edward can use frequentist (population-based) inferences,
strictly point estimation, and alternative foundations for parameter
uncertainty.

For example, Edward supports non-Bayesian methods such as generative
adversarial networks (GANs)
\citep{goodfellow2014generative}.
For more details, see the \href{/tutorials/gan}{GAN tutorial}.

In general, we think opening the door to non-Bayesian approaches is a
crucial feature for probabilistic programming. This enables advances
in other fields such as deep learning to be complementary: all is in
service for probabilistic models and thus it makes sense to combine
our efforts.

\subsubsection{Exact Inference}

In order to uncover conjugacy relationships between random variables
(if they exist), we use symbolic algebra on nodes in the computational
graph.  Users can then integrate out variables to automatically derive
classical Gibbs \citep{gelfand1990sampling},
mean-field updates \citep{bishop2006pattern}, and exact inference.

For example,  can calculate a conjugate posterior analytically by
using the \texttt{ed.complete_conditional} function:

\begin{lstlisting}[language=Python]
from edward.models import Bernoulli, Beta

# Beta-Bernoulli model
pi = Beta(1.0, 1.0)
x = Bernoulli(probs=pi, sample_shape=10)

# Beta posterior; it conditions on the sample tensor associated to x
pi_cond = ed.complete_conditional(pi)

# Generate samples from p(pi | x = NumPy array)
sess.run(pi_cond, {x: np.array([0, 1, 0, 0, 0, 0, 0, 0, 0, 1])})
\end{lstlisting}

\begin{center}\rule{3in}{0.4pt}\end{center}

The classes below inherit methods from base inference classes;
see the \href{/api/inference-development}{development page} for more
details.

{%sphinx

.. autoclass:: edward.inferences.VariationalInference
   :members:

.. autoclass:: edward.inferences.KLqp
   :members:

.. autoclass:: edward.inferences.ReparameterizationKLqp

.. autoclass:: edward.inferences.ReparameterizationKLKLqp

.. autoclass:: edward.inferences.ReparameterizationEntropyKLqp

.. autoclass:: edward.inferences.ScoreKLqp

.. autoclass:: edward.inferences.ScoreKLKLqp

.. autoclass:: edward.inferences.ScoreEntropyKLqp

.. autoclass:: edward.inferences.GANInference
   :members:

.. autoclass:: edward.inferences.BiGANInference
   :members:

.. autoclass:: edward.inferences.WGANInference
   :members:

.. autoclass:: edward.inferences.ImplicitKLqp
   :members:

.. autoclass:: edward.inferences.KLpq
   :members:

.. autoclass:: edward.inferences.MAP
   :members:

.. autoclass:: edward.inferences.Laplace
   :members:

.. autoclass:: edward.inferences.MonteCarlo
   :members:

.. autoclass:: edward.inferences.MetropolisHastings
   :members:

.. autoclass:: edward.inferences.Gibbs
   :members:

.. autoclass:: edward.inferences.HMC
   :members:

.. autoclass:: edward.inferences.SGLD
   :members:

.. autoclass:: edward.inferences.SGHMC
   :members:

.. automodule:: edward.inferences.conjugacy
   :members: complete_conditional

%}

\subsubsection{References}\label{references}