\documentclass{report}

\usepackage{tikz}
\usepackage{graphicx}
\usepackage{amsmath}
\usepackage{palatino}
\usepackage{siunitx}
\usepackage{hyperref}
\usepackage{listings}

% tables
\usepackage{booktabs}
\usepackage{tabularx}

% begin tikz
\usepackage{tikz}
\usetikzlibrary{graphs,graphdrawing,matrix,decorations.pathreplacing}
\usegdlibrary{layered}
% end tikz

% biblio
\usepackage[style=authoryear]{biblatex}
\addbibresource{references.bib}

\input{macros.tex}

\title{Moist Convection ML}
\author{Noah D. Brenowitz}
\date{\today}
\usepackage{dsfont}
\newcommand{\1}[1]{\mathds{1}\left[#1\right]}
\begin{document}
\maketitle
\tableofcontents

\chapter*{Notation and Physical Constants}
\label{ch:notation}
\begin{table}
  \centering
  \begin{tabularx}{\textwidth}{lX}
    \toprule
    Symbol & Description\\
    \toprule
    $n$ & number of samples \\
    $m$ &  number of features\\
    $X$ & $s \times m$ data matrix of predictors\\
    $Y$ & $s \times \cdot $ data matrix of predictands\\
    \bottomrule
  \end{tabularx}

  \caption{List of common notations}
  \label{tab:constants}
\end{table}

\begin{table}
  \centering
  \begin{tabularx}{\textwidth}{lcX}
    \toprule
    Variable & Value & Description\\
    \toprule
    $c_p$ & \SI{1004}{J/K/kg} & Heat capacity of air\\
    $L_v$ & \SI{2.5e6}{J/kg} & Latent heat of vaporization\\
    \bottomrule
  \end{tabularx}

  \caption{List of physical constants}
  \label{tab:constants}
\end{table}
\chapter{Introduction}

\chapter{Training Data}

\section{System for Atmospheric Modeling}
\label{sec:sam}

The System for Atmospheric Modeling (SAM) uses a different set of prognostic
equations \autocite{Khairoutdinov2003}. These are given by

\begin{subequations}
  \label{eq:sam}
  \begin{align}
    &\totd{\bu}{t} + ( f  + \beta y) \mathbf{k}\times \bu = - \nabla \phi \\
    &\totd{w}{t} = -\nabla \phi + g B \label{eq:w-full}\\
    &\totd{h_L}{t}  = Q_{rad}  - \frac{1}{\rho_0} \pd{}{z} \left( L_c P_r + L_s P_s + L_s P_g \right)\\
    &\totd{q_T}{t} = -  \dot{q}_p^{\text{micro}} \label{eq:sam-qT}\\
    &\totd{q_p}{t} = \frac{1}{\rho_0} \pd{}{z} \left(  P_r +  P_s + P_g \right) + \dot{q}_p^{\text{micro}}\\
    &\nabla \cdot \bu + \frac{1}{\rho_0} \pd{\rho_0 w}{z}  = 0.
  \end{align}
\end{subequations}
I have neglected the sub-grid-scale flux terms in the formulation above since
they are not relevant to the problem considered in this report. The temperature
and humidity variables introduced in the previous section have been replaced
here by
\begin{description}
\item[Liquid/ice water static energy] $h_L = c_p T +gz - L_c (q_c + q_r) - L_s
  (q_i + q_s + q_g)$,
\item[Total nonprecipitating water] $q_T = q_v + q_c + q_i$, and
\item[Total precipitating water] $q_p = q_r + q_s + q_g$.
\end{description}
Note that $h_L$ is only an appropriate variable when hydrostatic balance or
anelastic equations are satisfied. Otherwise, potential temperature should be
used. There are a number of diagnostic equations which can be solved to
determine the temperature, and all the mixing ratios for the different species
of precipitating and non-precipitating water. Perhaps most importantly, the
water vapor is assumed to be at or below an approximate saturation value so that
\[q_v = \min(q_T, q_{sat}(p_0, T)),\]
where
\[ q_{sat} = q_{sw} (1-\omega_i) + \omega_i q_{si}\]
is a convex combination of the saturation mixing ratios of vapor with respect to
ice and liquid water.

A consequence of this diagnostic relation is that the latent
heating term due to condensation is not explicitly calculated. Instead, SAM
models the microphysical processes which govern the conversion from condensate
($\text{cloud water} + \text{cloud ice}$) to precipitation ($\text{rain} +
\text{snow} + \text{grauppel}$). These processes are given by
\[
  \dot{q}_p^{\text{micro}} = \text{accretion} - \text{evaporation} + \text{autoconversion}.
\]
A nice paper by \textcite{hernandez-duenas_minimal_2013} contains a more thorough
discussion of a similar set of microphysical equations, which can be helpful for
gaining intuition. Additional details about the diagnostic relations linking the
water species and the prognostic variables $q_T$, $h_L$, and $q_p$ are available
in Appendix \ref{sec:diag-q} and in the original SAM paper by \textcite{Khairoutdinov2003}.

This formulation is convenient for numerical modeling purposes, but
moist-convective processes are often understood as a coupling between dry
dynamics and moist variables because the bouyancy is related primarily to
temperature, rather than moist static energy.
For instance, the circulation due to the monsoons and MJO can be understood
roughly as the response to a imposed heating pattern \autocite{Gill1980}, and
the multiscale theories of Biello and Majda rely upon asympotic analysis of the
latent heating.

\section{Near-global Model Configuration}
\label{sec:model-config}

We configure the model in the same way as \textcite{Bretherton2015}.

The size of the domain is (5120, 2560) grid points with a grid size of
\SI{4}{\km}, which in physical units is \SI{20480}{\km} by \SI{12800}{\km}.
We define the central 2560 kilometers in the y-direction as the tropics.
This is 16 coarse grained grid boxes out of total of 64, which is [24, 40) in
0-indexed notation.

\begin{figure}[ht]
  \centering
  \includegraphics{images/cld.png}
  \caption{\label{fig:cld}Snapshot of the cloud cover fraction field from the NGAqua simulation.}
\end{figure}

% \begin{tikzpicture}[scale=.5]
%   \draw (0,0) rectangle (20.480, 12.800);
%   \draw[step=.160] (0,0) grid (20.480, 12.800);
% \end{tikzpicture}

\section{Data Availability}

The coarse-grained NGAqua data is available on the olympus file server in the UW Atmospheric Sciences department as well as in a google cloud storage bucket:
\verb|nbren12-largedata/data/id/726a6fd3430d51d5a2af277fb1ace0c464b1dc48|

\section{Model Outputs}

The model outputs a collection of three dimensional and two dimensional fields
at a sampling interval of three hours.
Because the model uses an Arakawa C-Grid, some of the variables are staggered
while others are centered.
Figure \ref{fig:arakawa-c-grid} provides an illustration of this.

\begin{figure}
  \centering

  \begin{tikzpicture}[scale=2]

    \draw (-1, 0) -- (3,0);
    \draw (0, -1) -- (0,3);
    \draw (2, -1) -- (2,3);
    \draw (-1, 2) -- (3,2);

    \node at (1,1) {$q_v$, $q_p$, $q_n$, $\phi$, $s_l$};
    \node[fill=white] at (1,0) {$u_{i}$};
    \node[fill=white] at (1,2) {$u_{i+1}$};
    \node[fill=white] at (2,1) {$v_{i+1}$};
    \node[fill=white] at (0,1) {$v_{i}$};
  \end{tikzpicture}

  \caption{Arakawa C-Grid.
    The velocities are represented on the faces, while the scalar quantities are
    cell-centered.
    This plot only shows the horizontal grid, but the vertical velocity $w$ is
    staggered in the vertical direction.}
  \label{fig:arakawa-c-grid}
\end{figure}

\section{Coarse-graining and Destaggering}
\label{sec:post-processing}

The main post processing steps are

\begin{enumerate}
\item Coarse-graining, and
\item computing the apparent heat and moisture source due to convection.
\end{enumerate}

The coarse graining procedure is relatively straightforward.
SAM outputs the data on a grid with a \SI{4}{\km} resolution.
We can describe this coarse-graining mathematically.
Let $f(x,y,z,t)$ be some three dimensional field outputed by the atmospheric
model.
Then, divide the domain into coarse grained grid boxes $C_{i,j}$ which represent the
typical GCM grid box. These grid boxes are defined by

\[
  C_{i,j} = \{(x,y):   j \Delta x \leq x < (j+1) \Delta x
  \quad \cap\quad j \Delta y \leq y < (j+1) \Delta y \},
\]
where $\Delta x$ and $\Delta y$ are the size of the GCM grid box (e.g.
\SI{160}{\km}). Averaging over these grid boxes gives the coarse-grained field
\[
  \overline{f}_{i,j} = \int_{C_{ij}} f dA.
\]

\begin{figure}
  \centering
  \begin{tikzpicture}
    \draw (0,0) rectangle (6,6);
    \draw[step=1.5mm] (0,0) grid (6,6);
    \draw[decorate,decoration={brace,amplitude=10pt,mirror,raise=4pt}] (0,0) -- (6,0);
    \node at (3,-.7cm) {$\Delta x = \SI{160}{\km}$};
  \end{tikzpicture}
  \caption{Coarse-graining procedure. The coarse-grained grid boxes have a
    length of \SI{160}{km} and contains $40^2$ fine scale grid boxes.}
  \label{fig:coarse-grain}
\end{figure}

Figure \ref{fig:preprocess} contains a flow chart describing the preprocessing pipeline.

\begin{figure}
  \centering
  \begin{tikzpicture}[ every node/.style={draw} ]
    \graph[layered layout]{

      Input data -> Destagger $u$ and $v$ -> a/ Coarse grain all variables;
      Input data -> a; a -> w/Destagger coarse grained $\overline{w}$; {a, w} ->
      Reshape data and fit models!

    };
  \end{tikzpicture}

  \caption{Preprocessing pipeline flowchart}
  \label{fig:preprocess}
\end{figure}
\section{Apparent Heating and Moistening}
\label{sec:q1q2}

In SAM, the conserved variables are the liquid-ice static energy and the total non-precipitating water. The liquid static energy is given in temperature units by
\[ s_l = T + \frac{g}{c_p} z - L_c(q_n + q_p),\]
where $q_n$ is the total cloud condensate, $q_p$ is precipitation, and $L_c$ is the latent heat of condensation. This definition is an approximation which neglects the presence of the frozen phase of water. The total water non-precipitating water is just given by
$q_t = q_v + q_n.$

Then, for our purposes, the apparent heat source is given by
\[Q_1 = \partial_t {\bar{s}_l} + \overline{ \mathbf{v} }\cdot \overline{\nabla} \bar{s}_l, \]
and the apparent drying is given by
\[Q_2 = - \frac{L_c}{c_p} \left[\partial_t {\bar{q}_t} +\overline{ \mathbf{v} } \cdot \overline{\nabla} \bar{q}_t\right].\]
The factor $-\frac{L_c}{c_p}$ is used to ensure that this quantity also has units K/day. Comparing to the original prognostic equations for SAM shows that $Q_1$ contains the source term  $Q_r$ to the temperature equation which represents radiative transfer, which is usually a cooling tendency. For the purposes of cumulus parametrization, it might be possible to assume this is known from other sources (e.g. a radiative transfer code such as RRTMG). Therefore, we will also define the convective component of the apparent heating as $Q_{1c} = Q_1 - Q_r$.

All the differential operators in these two expression represent a finite
differencing taken on the coarse grid, and we will use centered differences to
compute these. Specifically, the formulas for the advection terms are given
by
\renewcommand{\bf}{\bar{f}_{i,j}}

% \[(A_f)_{i,j} = \left( \bar{f}_{i+1,j,k} - \bar{f}_{i-1,j,k} \right) \frac{\bar{u}_{i,j,k}}{2 \Delta x}
%               + \left( \bar{f}_{i,j+1,k} - \bar{f}_{i,j-1,k} \right) \frac{\bar{v}_{i,j,k}}{2 \Delta y}
%               + \left(  \bar{f}_{i,j,k+1} - \bar{f}_{i,j,k-1} \right) \frac{\bar{v}_{i,j,k}}{z_{k+1} - z_{k-1}}
%             \]

\begin{align}
  (A_f)_{i,j,k} = &\left( \bar{f}_{i+1,j,k} - \bar{f}_{i-1,j,k} \right) \frac{\bar{u}_{i,j,k}}{2 \Delta x}\\
              +&\left( \bar{f}_{i,j+1,k} - \bar{f}_{i,j-1,k} \right) \frac{\bar{v}_{i,j,k}}{2 \Delta y}\nonumber\\
              +& \left(  \bar{f}_{i,j,k+1} - \bar{f}_{i,j,k-1} \right) \frac{\bar{w}_{i,j,k}}{z_{k+1} - z_{k-1}}.\nonumber
\end{align}
We have taken advantage of the constant horizontal grid spacing and the
collocation of all the coarse grained variables.

The numerical estimates of $Q_1$ and $Q_2$ depend on these simple expressions.
The apparent heating is given by
\begin{equation}
  \label{eq:q1-num}
  Q_1^{n+1/2} = \frac{\bar{s_l}^{n+1} - \bar{s_l}^{n} }{\Delta t}
            +  A^{n}_{s_l} .
\end{equation}
where the spatial index $i,j,k$ has been dropped. Similarly, the apparent
drying is given by
\begin{equation}
  \label{eq:q2-num}
  -\frac{c_p}{L_v} Q_2^{n+1/2} = \frac{\bar{q_T}^{n+1} - \bar{q_T}^{n} }{\Delta t}
            +  A^{n}_{q_T} .
\end{equation}
The factor $\frac{c_p}{L_v}$ ensures that $Q_2$ has units of temperature over
time, just like $Q_1$. These and other important physical quantities are
described in \autoref{tab:constants}.

\section{Reshaping data}

Most machine learning algorithms require two dimensional matrices as inputs, but
the SAM produces four-dimensional datasets of humidity, temperature, and other
atmopsheric variables.
To reshape this multivariate three-dimensional data into a single vector for
machine learning, we must define which dimensions of data are physically
relevant.
We call these ``feature dimensions'' and the remaining non-relevant dimensions
``sample dimensions''. The columns of the two-dimnsional data matrix $X$ will
correspond to samples taken along the sample dimensions, and the rows will
correspond to data taken from the feature dimensions.

Because the time-scale of deep atmopsheric convection is so fast, the inputs for
the convection scheme should be non-local in the vertical direction, so the only
feature dimension is $z$.
The remaining dimensions of the data---$x$, $y$, and time---are the sample
dimensions.
Therefore, given a single field of the data $f[x,y,z,t]$, then a particular sample vector
\[
  \mathbf{f}[x,y,t] =
    \begin{bmatrix}
      f[x,y,1,t] \\
      f[x,y,2,t] \\
      \vdots\\
      f[x,y,n_z,t]
    \end{bmatrix}
\]
is defined for each horizontal location and time point. Then, we can tabulate
all these vectors in a two dimensional array given by
\newcommand{\fb}{\mathbf{f}}
\[
  X_f =
  \begin{bmatrix}
    \fb[1,1,1], \fb[2,1,1], \ldots,\fb[x,y+1,t], \fb[x+1,y+1,t],\ldots,\fb[n_x, n_y,
    n_t]
  \end{bmatrix}
\]

In addition to being 4 dimensional, the data are multivariate, and contains
multiple atmopspheric fields, with different physical units. For most of our
analysis, we use $q_T$ and $s_L$ to predict the amount of latent heating due to
convection. To handle the multivariate case, we simply stack the data matrices
for each variable vertically, so that the full data matrix $X_{\{s_l, q_T\}}$ is given by
\[
  X_{\{s_l, q_T\}}=\begin{bmatrix}
    X_{s_l}\\
    X_{q_T}
  \end{bmatrix}.
\]
We define data matrices for more than two variables.

Finally, we must introduce the temporal shifting operator, which we will use to
create models for the dynamics. When time is the only sample dimension, this
operator is trivial, but having multiple sample dimensions complicates matters.
In any case, the time shifting  operator $L$ is defined by
\[
  LX =
  \begin{bmatrix}
    \mathbf{x}[1,1,2],\ldots,\mathbf{x}[x, y, t+1], \ldots, \mathbf{x}[n_x, n_y, t]
  \end{bmatrix}.
\]
Because we use this operator extensively below, we will adopt the notation that $X' =
LX$, so that $X'$ are the data shifted forward by one time sample.

\chapter{Methods}

\section{Machine Learning for dynamical systems}

The ultimate goal of this work is to estimate or simulate the unknown source
terms. Essentially we need an effective way to draw samples
from
\[ \rho(x_{t+\Delta t}, t + \Delta t |x_{[s < t]}).\] There are two clear problems here.
First, this probability distribution depends on the whole time course of
$x$ leading up to time $t$.
Ideally we want to create a Markov description of the data, a task which is
known as \emph{embedding}.
Supposing $z_t$ is a suitable embedding of $x_t$---Takens''' delay embedding is a natural choice---the conditional pdf becomes
\[\rho(z_{t+\Delta t}, t+ \Delta t| z_t, t),\]
and we must characterize this conditional density.
We also might prefer to use the infinitesmimal generator
\[L_z = \lim_{\Delta t \rightarrow 0} \frac{\rho(z_{t+\Delta t}, t+ \Delta t| z_t,
    t) - \delta(z_{t+\Delta t} - z_t) }{\Delta t}.\]

There are also a series of functions $f_i$ which we trust capture some aspect of
the dynamics.
For example, we should trust the dynamical core, turbulence, and radiation
schemes, and not attempt to \emph{learn} a GCM from scratch.
But the functions $f_i$ are not specified in the pdf at all, and we might not
even know them with perfect accuracy. We can include them in the statistical
model as follows
\[\rho(z_{t+\Delta t}, t+ \Delta t| z_t, y_i, t) p(y_i|z_t, t) \]
where $y_i = f_i(z_t) + \epsilon_i$.

\section{Maximum Covariance Analysis}
\label{sec:mca}

Maximum Covariance Analysis (MCA) finds the modes which maximize the cross
covariance between an input matrix $X$ and output matrix $Y$.
If the mean of $X$ and $Y$ along the columns vanishes, then the covariance
matrix is given by
\[C=X'Y.\]
Then, we take an SVD of this matrix to get
\[C=U\Sigma V'.\] We will call the columns of $U$ the input \emph{loadings}, and
the columns of $V$ the output loadings.
The loading vectors each orthornmal bases of the input and output features
spaces.
By projecting the data onto these loadings, we obtain the input and output
\emph{scores}, which are respectively defined by $S_x = X U''''''$ and $S_y=YV'$.

For our analysis, we consider the case where $X$ is the matrix of
horizontal-temporal samples of profiles of $q_T$ and $s_L$, and $Y$ contains
samples of $Q_{1c}$ and $Q_2$. In other words, there are $2\cdot n_z$ columns of
$X$ and $Y$ corresponding. Moreover, the columns of $X$ and $Y$ are weighted by
the square root of the corresponding layer mass. The behavior of the NGAqua
dataset appears to reduce to a two mode structure, and we show the behavior of
these two modes in Figures \ref{fig:mca-loadings} and \ref{fig:mca-ts}.

\begin{figure}
  \centering
  \includegraphics[height=5in]{images/mca_modes.pdf}
  \caption{Loadings for first two MCA modes.}
  \label{fig:mca-loadings}
\end{figure}
\begin{figure}
  \centering
  \includegraphics[width=\textwidth]{images/mca_ts.png}
  \caption{Time series of first MCA mode scores for a single location at the
    equator.
    Input scores (top) and output scores (bottom).
    The sign and amplitude of these modes is given by the raw output of the
    scheme, and does not correspond to the plots in \autoref{fig:mca-loadings}.}
  \label{fig:mca-ts}
\end{figure}

\section{Linear models}

\begin{figure}[ht]
  \centering
  \includegraphics[width=\textwidth]{images/lrf_lm.png}
  \caption{\label{fig:lrf-lm}Linear response matrix for linear regression
    pipeline.
    The full outputs are regressed onto the columns of $X$ with a variance
    larger than .001.
    This thresholding procedure ensures that the uppper atmosphere
    moistures---which vanishes---does not enter the regression analysis.}
\end{figure}

\begin{figure}[ht]
  \centering
  \includegraphics[width=\textwidth]{images/lrf_mca4.png}
  \caption{\label{fig:lrf-mca}Linear response matrix for MCA linear regression
    pipeline.
    The first step is to compute the X scores, and then the full Y outputs are
    regressed onto these scores.}
\end{figure}

\begin{figure}[ht]
  \centering
  \includegraphics[width=5in]{images/mca-regression-coef}
  \caption{\label{fig:mca-regression-coef}Regression coefficients for each
    whitened MCA mode.
    These are the resulting heating patterns if the z-score of the given mode is
    1.0.
    These patterns do not need to look like output loadings shown in
    \autoref{fig:mca-loadings}, despite their similarity.}
\end{figure}

\section{Time stepping with Neural Networks}

The data we are using are only evaulated with a coarse sampling time step of 3 hours. On the other hand, we will probably use 10-20 minute time step for the coarse resolution model. This means that the dynamical model we are trying to fit is
$$ x^i_{n+1} = \underbrace{f(f(\ldots f}_{\text{m times}}(x^i_n))) + \int_{t_n}^{t_{n+1}} g(x(t), t) dt$$
where $i$ is the horizontal spatial index, and $n$ is the time step. The number of times the function $f$ is applied is $m=\frac{\Delta t}{h}$ where $h$ is the GCMs time step, and $\Delta t$ is the sampling interval of the stored output. The integral on the right represents the approximately known terms such as advection, and $f$ represents the unknown source terms.

We solve a minimization problem to find $f$. This is given by
$$
\min_{a} \lim_{m \rightarrow \infty} \sum_{i,n} ||x^{i}_{n+1} - F^{(m)} x^i_{n} - g_n^{i}||_W^2 \quad \text{s.t.}\quad F^{(m)}(\cdot) = \underbrace{f(f(\ldots f}_{\text{m times}}(\cdot))),\ f(x) = x +  \frac{ \Delta t}{m} a(x).
$$
Intuitively, the forward operator $F^{(m)}$ is the result applying $m$ forward euler steps to the system $a$.

Let's try performing this fit. First, we need to import the appropriate models, and load the data

\subsection{Literature Review}
\label{sec:blowup-rnn}

Unfortunately, applying a function repeatedly like often causes solutions to
explode.
This issue is discussed known in recurrent neural network (RNN) community
\autocite[See Ch.
10.7]{Goodfellow2016}.
They discuss something known as Echo State Networks (ESN), which must repeatedly
confront this issue. Apparently, this blow up can be controlled in two ways.
\begin{enumerate}
\item Control the spectral radius of the Jacobian. I.e. ensure that
  \[\rho \left( \frac{\partial x^{n+1}}{\partial x^n} \right) < 1\]

\item Use squashing nonlinearities like $\tanh$, and allow larger spectral radius.
\end{enumerate}

I still need to figure out how exactly they control the spectral radius of
neural network.

The deep learning literature discusses the issue of exploding gradients as more
an issue with back-propagation of gradients than forward propagation or
predictions. However, I think the solutions are the same.

\section{Time stepping}

Want to formulate a neural network scheme which has inputs that do not depend on the time step.
The various physical processes in a climate model update the state sequentially, so that each process sees a state updated by the previous process.
Unfortunately, these processes can dramatically change the state by up to a few degrees K over a large time step, which makes the inputs for the neural networks scheme depend on the time step.
This is not much of an issue for physics based parameterizations, but machine learning schemes cannot be extrapolated to different time steps then they were trained on if their inputs depend on the time steps.
Therefore, we need to make the inputs to an ML scheme invariant to the time step, which we accomplish with the following time-stepper
\begin{align}
 x^* &= x + h g(x, t) \\
 x^{+} &= x^* + h f(x, g(x, t), t; \alpha).
\end{align}

\section{Enforcing physical constraints}

\subsection{Positive humidity}

We would like to ensure that $q> 0$ in a mass conserving way so that it doesn't alter the precipitation.
To do this, we first assume that
\[ Pq =
  \begin{cases}
    \alpha q & q >= \epsilon \\
    \epsilon & q < \epsilon
  \end{cases}.
\]
Then, choosing
\[\alpha = \frac{\langle q \rangle - \epsilon \langle \1{q < \epsilon} \rangle}{\langle \1{q \geq \epsilon} q \rangle}\]
ensures mass conservation.

\section{Mixture model}

We first train separate models on different regions in parallel, and then switch between the networks using a mixture modeling approach.
We will divide the data into 5 meridionally overallaping regions, and then train the networks on each region in isolation. These regions are
\begin{itemize}
\item Deep tropics
\item 2 Sub-tropics regions
\item 2 mid-lat regions
\end{itemize}
Because this dataset is so large, each region will still have many sampling points, but we do not join the sub-tropcs and mid-latitude regions for the northern and southern hemisphere because there could be climatological difference between these regions.
These regions are separated by distinct rainfall regimes.

The coarse-grained indices corresponding to a given latidue is given by $a \phi / \SI{160}{\km}$ which is $\frac{a\pi}{180 \cdot 160} \phi $ if $\phi$ is in degrees. Therefore the indices of the regions above are
\begin{enumerate}
\item 0,18 (so midlat)
\item 16,28 (so sub tropics)
\item 26,38 (deep tropics)
\item 36,48 (no sub tropics)
\item 46,64 (no midlat)
\end{enumerate}

\printbibliography
\appendix

\chapter{Source code}
\label{sec:source}

% \lstinputlisting[language=python]{../lib/linear_regression.py}

\end{document}

% Local Variables:
% TeX-master: t
% TeX-PDF-mode: t
% TeX-engine: luatex
% End:


\documentclass[journal,hidelinks]{IEEEtran}
\usepackage[utf8]{inputenc}
\usepackage[
  pdftitle={Final Exam},
  pdfauthor={Andrei Purcarus},
  pdfsubject={ECSE-534 -- Analog Microelectronics}
]{hyperref}
\usepackage{graphicx}
\usepackage[all]{hypcap}
\usepackage{cleveref}
\usepackage{indentfirst}
\usepackage[per-mode=symbol]{siunitx}
\usepackage{amsmath}

\title{ECSE-534 \\ Analog Microelectronics \\ Final Exam}
\author{Andrei~Purcarus,~260631911,~\IEEEmembership{McGill~University} \\ \href{mailto:andrei.purcaruscraciun@mail.mcgill.ca}{andrei.purcaruscraciun@mail.mcgill.ca}}

\begin{document}
\sloppy

\maketitle

\section{Introduction}

\IEEEPARstart{T}{his} report follows the design, simulation, and analysis of an anti-aliasing filter for a $\Delta \Sigma$ data converter using a 0.13 micron process from IBM. We used Cadence to simulate the design in said process. The filter was required to adhere to the topology shown in \Cref{fig:filter_topology} and meet the following specifications:
\begin{itemize}
  \item A DC gain of $\SI{1}{\volt\per\volt}$.
  \item A passband from DC to $\SI{100}{\kilo\hertz}$.
  \item A maximum attenuation of $\SI{0.1}{\deci\bel}$ in the passband.
  \item A maximum phase shift of $\SI{10}{\degree}$ in the passband.
  \item A minimum attenuation of $\SI{40}{\deci\bel}$ at frequencies over $\SI{15}{\mega\hertz}$.
  \item An input resistance of at least $\SI{1}{\kilo\ohm}$.
  \item An output resistance of at most $\SI{20}{\ohm}$.
  \item An output voltage swing of $\SI{0.9}{\volt}$ around an analog ground level of $\SI{0.6}{\volt}$.
  \item A maximum RMS noise level of $\SI{100}{\micro\volt}$.
\end{itemize}

The filter must meet these specifications while driving a $\SI{1}{\pico\farad}$ load capacitance that represents the input capacitance of the $\Delta \Sigma$ data converter.

\begin{figure}[!htb]
  \centering
  \includegraphics[width=\columnwidth]{schematics/filter_topology.png}
  \caption{A schematic of the second-order anti-aliasing filter topology.}
  \label{fig:filter_topology}
\end{figure}

To meet these requirements, we first calculated the required values for the passive components of the filter. Then, we modified the operational amplifier we designed in the past assignments to meet the specifications. Next, we assembled the filter and verified that it meets the requirements. Finally, we discussed a rough sketch of the layout of the filter.

\begin{figure*}[!htb]
  \centering
  \includegraphics[width=\textwidth]{schematics/folded_cascode.png}
  \caption{A schematic of the operational amplifier designed in past assignments.}
  \label{fig:folded_cascode}
\end{figure*}

\begin{figure*}[!htb]
  \centering
  \includegraphics[width=\textwidth]{schematics/folded_cascode_2.png}
  \caption{A schematic of the modified operational amplifier made to meet the requirements.}
  \label{fig:folded_cascode_2}
\end{figure*}

\begin{figure*}[!htb]
  \centering
  \includegraphics[width=\textwidth]{schematics/filter.png}
  \caption{A schematic of the anti-aliasing filter.}
  \label{fig:filter}
\end{figure*}

\section{Filter Design}

We first translated the given specifications into restrictions on our circuit. We started by deriving the transfer function of the filter as
\begin{align}
H(s) &= \frac{-R}{1 + s R C} \frac{1}{R/2} \frac{1/2}{1 + s R C} \\
     &= \frac{-1}{(1 + s R C)^2}
\end{align}
This result tells us that the DC gain is $-1$ and the bandwidth is given by $f_{3dB} = 1 / 2 \pi R C$.

In order to gain more insight into the operation of the filter, we added a relative mismatch $\Delta$ to the components in the feedback network. We thus obtained
\begin{align}
H(s) &= \frac{-R (1 + \Delta_R)}{1 + s R C (1 + \Delta_R) (1 + \Delta_C)} \frac{1}{R/2} \frac{1/2}{1 + s R C} \\
     &\approx \frac{-R (1 + \Delta_R)}{1 + s R C (1 + \Delta_R + \Delta_C)} \frac{1}{R/2} \frac{1/2}{1 + s R C}
\end{align}
This result tells us that the DC gain can be approximated as $-(1 + \Delta_R)$ and that there are two poles formed, one at $f_1 = 1 / 2 \pi R C$ and the other at $f_2 = 1 / 2 \pi R C (1 + \Delta_R + \Delta_C)$.

The given DC gain requirement means that the feedback resistors in the circuit must match well. In addition, the DC gain of the operational amplifier must be high, say at least $\SI{60}{\deci\bel}$.

The given attenuation requirements mean that we must have $f_{3dB} \gg \SI{100}{\kilo\hertz}$ and $f_{3db} \ll \SI{15}{\mega\hertz}$. Since a second order filter has a roll-off of about $\SI{40}{\deci\bel}$ per decade, this translates approximately to $f_{3db} < \SI{1.5}{\mega\hertz}$.

The given input resistance requirement means that $R > \SI{1}{\kilo\hertz}$. The given output resistance requirement means that we must have $2 R_{out} < \SI{20}{\ohm}$ for the operational amplifier, where $R_{out}$ is the output resistance of the amplifier in the unity gain configuration.

The given voltage swing requirements translate directly into equivalent requirements for the operational amplifier.

The given noise requirement must be separated between two sources: the thermal noise generated by the feedback network and the noise generated by the amplifier. We therefore allocate an RMS noise budget of $\SI{50}{\micro\volt}$ to each.

The RMS thermal noise generated by the feedback network can be approximated as
\begin{align}
v_{n,rms} = \sqrt{\frac{kT}{C} + \frac{kT}{4C}}
\end{align}
Therefore, we have
\begin{align}
v_{n,rms} &< \SI{50}{\micro\volt} \\
\sqrt{\frac{kT}{C} + \frac{kT}{4C}} &< \SI{50}{\micro\volt} \\
C &> \SI{2}{\pico\farad}
\end{align}

The noise generated by the amplifier is harder to quantify. However, since the feedback gain of our circuit is $1 / 2$, the output spectral noise density of the amplifier in this circuit will be equivalent to the input-referred spectral noise density measured in open loop simulation times $2$. Thus, we require an input-referred RMS noise level of at most $\SI{50}{\micro\volt} / \sqrt{2} = \SI{35}{\micro\volt}$.

Therefore, the requirements for the feedback network are
\begin{equation}
R > \SI{1}{\kilo\ohm}
\end{equation}
\begin{equation}
C > \SI{2}{\pico\farad}
\end{equation}
\begin{equation}
\SI{100}{\kilo\hertz} \ll \frac{1}{2 \pi R C} < \SI{1.5}{\mega\hertz}
\end{equation}

To minimize the size of the capacitors used, we chose to use $C = \SI{3}{\pico\farad}$. Then, to allow for at least a $\SI{20}{\percent}$ margin on the upper bandwidth, we chose to use $f_{3dB} = \SI{1}{\mega\hertz}$, and thus $R = \SI{53}{\kilo\ohm}$.

\section{Operational Amplifier Design}

From the previous section, the main requirements for the operational amplifier are a DC gain of at least $\SI{60}{\deci\bel}$, a maximum output resistance of $\SI{10}{\ohm}$ in the unity gain configuration, and an input-referred RMS noise level of at most $\SI{35}{\micro\volt}$ over the given bandwidth. In addition, we require that the unity gain frequency of the amplifier should be at least 10 times our chosen filter bandwidth, at $\SI{10}{\mega\hertz}$.

To meet these specifications, we reused the operational amplifier designed in the past assignments. A schematic is shown in \Cref{fig:folded_cascode}. This amplifier has a DC gain of $\SI{73}{\deci\bel}$, a unity gain bandwidth of $\SI{40}{\mega\hertz}$, an output resistance in the unity gain configuration of $\SI{12.9}{\ohm}$, and a total input-referred RMS noise of $\SI{65}{\micro\volt}$ between $\SI{1}{\hertz}$ and $\SI{100}{\kilo\hertz}$.

These results show that the amplifier does not meet the specifications for noise and output resistance. In order to modify the amplifier to meet the specifications, we performed a series of transformations on our initial circuit.

A noise analysis in Cadence indicated that the main contributors to the noise level were transistors $T_0$, $T_1$, $T_3$, and $T_4$, with a total contribution of $\SI{92.68}{\percent}$. Since flicker noise is inversely proportional to transistor area, we needed to scale the widths of these transistors upward. We achieved this by scaling the widths of $T_0$, $T_1$, $T_3$, and $T_4$ by a factor of $4$, and then scaling the width of $T_2$ to provide sufficient current to $T_0$ and $T_1$ to avoid disturbing the operating point of the other transistors in the circuit. This transistor ended up being scaled by a factor of $5$.
In addition, to meet the output resistance specification, we needed to scale the current in the output branch upward. We achieved this by scaling the widths of both $T_7$ and $T_{16}$ by a factor of $2$.
This also had the effect of scaling our bandwidth upward, so we scaled $C_c$ to $\SI{0.72}{\pico\farad}$ and $R_c$ to $\SI{3.3}{\kilo\ohm}$ to compensate.
The resulting amplifier is shown in \Cref{fig:folded_cascode_2}.

We then measured the amplifier's characteristics to confirm that it now met the specifications. The amplifier now had a DC gain of $\SI{77}{\deci\bel}$, a unity gain bandwidth of $\SI{53}{\mega\hertz}$, an output resistance in the unity gain configuration of $\SI{4.1}{\ohm}$, and a total input-referred RMS noise of $\SI{32}{\micro\volt}$ between $\SI{1}{\hertz}$ and $\SI{100}{\kilo\hertz}$. The first two poles were also moved to $\SI{8}{\kilo\hertz}$ and $\SI{102}{\mega\hertz}$, and the first zero was moved to $\SI{124}{\mega\hertz}$, which are very close to the values they initially had. In addition, we verified that the amplifier was still stable, with a phase margin of $\SI{57}{\degree}$.

\section{Putting It All Together}

We next assembled the circuit together as previously described. The result is shown in \Cref{fig:filter}. Note that we split the resistors into units of size $R/4$ in order to better match them in layout, and we split the capacitors into units of size $C$ for the same reason. After some testing, we also changed the value of $R$ to $\SI{40}{\kilo\ohm}$ in order to fully meet the specifications.

To test the performance of the filter, we used the circuit shown in \Cref{fig:filter_tb}, which has a load capacitance of $\SI{1}{\pico\farad}$.

\begin{figure}[!htb]
  \centering
  \includegraphics[width=\columnwidth]{schematics/filter_tb.png}
  \caption{A schematic of the test-bench used to measure the AC and transient performance of the filter.}
  \label{fig:filter_tb}
\end{figure}

We first measured the transient performance of the filter by using a $\SI{0.9}{\volt}$ peak-peak, $\SI{10}{\kilo\hertz}$ sine wave centered around $\SI{0.6}{\volt}$ as an input. The resulting input and output are shown in \Cref{fig:filter_tran}. This figure shows that the output signal has no significant distortion even at full range. In fact, we can compute the total harmonic distortion as only $\SI{0.040}{\percent}$, which shows that the circuit meets the voltage swing requirement of the $\Delta \Sigma$ converter.

\begin{figure}[!htb]
  \centering
  \includegraphics[width=\columnwidth]{results/filter_tran.png}
  \caption{Transient response of the filter for a $\SI{0.9}{\volt}$ peak-peak, $\SI{10}{\kilo\hertz}$ sine wave centered around $\SI{0.6}{\volt}$. The input waveform is shown in brown and the output waveform is shown in red.}
  \label{fig:filter_tran}
\end{figure}

We then measured the AC performance of the filter by using small signal analysis. The results are shown in \Cref{fig:filter_ac}. These results show that we have a DC gain of $\SI{0.99953}{\volt\per\volt}$, an attenuation of $\SI{0.053}{\deci\bel}$ and a phase shift of $\SI{8.83}{\degree}$ at $\SI{100}{\kilo\hertz}$, and an attenuation of $\SI{41.5}{\deci\bel}$ at $\SI{15}{\mega\hertz}$. Therefore, the filter meets all the AC requirements.

\begin{figure}[!htb]
  \centering
  \includegraphics[width=\columnwidth]{results/filter_ac.png}
  \caption{AC response of the filter. The plot on the left shows the gain in $\SI{}{\deci\bel}$ and the plot on the right shows the phase in $\SI{}{\degree}$.}
  \label{fig:filter_ac}
\end{figure}

We next measured the noise properties of the filter. After running an AC noise analysis and integrating the results from $\SI{1}{\hertz}$ to $\SI{100}{\kilo\hertz}$, we obtained the results shown in \Cref{fig:filter_noise}. This figure clearly shows that we have a total RMS output noise of $\SI{66}{\micro\volt}$, which meets the specified maximum noise level for the input to the $\Delta \Sigma$ converter.

\begin{figure}[!htb]
  \centering
  \includegraphics[width=\columnwidth]{results/filter_noise.png}
  \caption{Noise results for the filter over the bandwidth from $\SI{1}{\hertz}$ to $\SI{100}{\kilo\hertz}$.}
  \label{fig:filter_noise}
\end{figure}

Then, we measured the output resistance of the filter using the circuit shown in \Cref{fig:filter_tb_2}. With the load resistance set to $\SI{20}{\ohm}$ and the input set to $\SI{1}{\volt}$, we measured a small signal output voltage of $\SI{0.6984}{\volt}$. Using a simple voltage divider equation, we found that the output resistance of the filter was therefore $\SI{8.62}{\ohm}$, which is smaller than the maximum output resistance requirement.

\begin{figure}[!htb]
  \centering
  \includegraphics[width=\columnwidth]{schematics/filter_tb_2.png}
  \caption{A schematic of the test-bench used to measure the output resistance of the filter.}
  \label{fig:filter_tb_2}
\end{figure}

Finally, we measured the input resistance of the filter using the circuit shown in \Cref{fig:filter_tb_3}. With the signal resistance set to $\SI{40}{\kilo\ohm}$ and the input set to $\SI{1}{\volt}$, we measured a small signal output voltage of $\SI{0.49962}{\volt}$. Using a simple voltage divider equation, we found that the input resistance of the filter was therefore $\SI{39.98}{\kilo\ohm}$, which greatly exceeds the specification.

\begin{figure}[!htb]
  \centering
  \includegraphics[width=\columnwidth]{schematics/filter_tb_3.png}
  \caption{A schematic of the test-bench used to measure the input resistance of the filter.}
  \label{fig:filter_tb_3}
\end{figure}

\section{Layout}

Next, we planned out a rough sketch of the layout for the filter. As shown in \Cref{fig:folded_cascode_2}, we made all transistors multiples of a unit size, which reduces the error when trying to match them. We used a combination of the number of fingers to increase the length of a transistor and the multiplicity to increase the width of a transistor, thus ensuring that transistors can be made into rectangular shapes that are not too long and not too wide.

In addition, we made sure that all transistors that need to be matched have a multiplicity of at least $2$, which allows us to use a common centroid geometry to eliminate the effect of the first order component of the process gradient in producing matching error. An example of this is shown in \Cref{fig:layout_diff_pair}. In this figure, $T_0$ and $T_1$ are placed such that their centroids coincide. In addition, this figure shows the addition of dummy structures to the boundaries of the pair, which ensures that all transistors have a similar environment and thus creates a better matching. The dummy transistors would typically be connected to $V_{SS}$.

\begin{figure}[!htb]
  \centering
  \includegraphics[width=\columnwidth]{layout/diff_pair.png}
  \caption{A common centroid layout for a differential input pair with dummy structures at the boundary. Connections are not shown.}
  \label{fig:layout_diff_pair}
\end{figure}

For the passive components, matching was also critical since it controls the DC gain of the filter. In addition, mismatches can split the poles of the filter, causing ringing to occur. To ensure that these components are matched correctly, we again split them into subcomponents of unit size and used a common centroid geometry. A sketch of the layout of the resistors in the circuit is shown in \Cref{fig:layout_res}, and a sketch of the layout of the capacitors in the circuit is shown in \Cref{fig:layout_cap}.
We note here that while the matching of components is critical, the values of the components themselves are not. Since the $\Delta \Sigma$ converter oversamples at a rate of $\SI{16}{\mega\hertz}$ and the signal bandwidth is only $\SI{100}{\kilo\hertz}$, the resulting pole at around $\SI{1}{\mega\hertz}$ can vary by $\SI{\pm 20}{\percent}$ while still producing little passband attenuation and sufficient stopband attenuation.

\begin{figure}[!htb]
  \centering
  \includegraphics[width=\columnwidth]{layout/res.png}
  \caption{A common centroid layout for the resistors in the filter. Connections are not shown.}
  \label{fig:layout_res}
\end{figure}

\begin{figure}[!htb]
  \centering
  \includegraphics[width=\columnwidth]{layout/cap.png}
  \caption{A common centroid layout for the capacitors in the filter. Connections are not shown.}
  \label{fig:layout_cap}
\end{figure}

\section{Conclusions}

In conclusion, we designed an anti-aliasing filter capable of acting as a preprocessor for the $\Delta \Sigma$ converter specified in the examination question. This filter meets all of the specifications. In addition, we provided a sketch of the approach we would use to lay out such a filter.

\bibliographystyle{IEEEtran}
\bibliography{IEEEabrv,references}

\end{document}


\subsection{Enumeration types}
\label{subsec:library_of_transformations:type_level_transformations:enumeration_types}

\begin{figure}[H]
    \centering
    \begin{subfigure}{0.25\textwidth}
        \centering
        \includegraphics{images/05_library_of_transformations/02_type_level_transformations/04_enumeration_types/enum_type.pdf}
        \caption{$Tm_{Enum}$ with \\$name = .\type{Example}$ and \\$values = \{ \type{OPTION\_A},$\\$ \type{OPTION\_B}, \type{OPTION\_C} \}$}
        \label{fig:library_of_transformations:type_level_transformations:enumeration_types:visualisation:ecore}
    \end{subfigure}
    \\
    \begin{subfigure}{0.65\textwidth}
        \centering
        \input{images/05_library_of_transformations/02_type_level_transformations/04_enumeration_types/enum_as_node_types.tikz}
        \caption{$TG_{EnumNodes}$ with $name = .\type{Example}$ and\\$values = \{ \type{OPTION\_A}, \type{OPTION\_B}, \type{OPTION\_C} \}$}
        \label{fig:library_of_transformations:type_level_transformations:enumeration_types:visualisation:groove_nodes}
    \end{subfigure}
    \begin{subfigure}{0.25\textwidth}
        \centering
        \input{images/05_library_of_transformations/02_type_level_transformations/04_enumeration_types/enum_as_flags.tikz}
        \caption{$TG_{EnumFlags}$ with \\$name = .\type{Example}$ and \\$values = \{ \type{OPTION\_A},$\\$ \type{OPTION\_B}, \type{OPTION\_C} \}$}
        \label{fig:library_of_transformations:type_level_transformations:enumeration_types:visualisation:groove_flags}
    \end{subfigure}
    \caption{Visualisations of the transformations of enumeration types}
    \label{fig:library_of_transformations:type_level_transformations:enumeration_types:visualisation}
\end{figure}

This section will define the transformation of an enumeration type. Within this transformation, a new enumeration type is introduced, including its possible values. The Ecore type model that introduces such a subclass is defined as follows:

\begin{defin}[Type model $Tm_{Enum}$]
\label{defin:library_of_transformations:type_level_transformations:enumeration_types:tmod_enum}
Let $Tm_{Enum}$ be the type model containing a enumeration type with identifier $name$. The values of this enumeration type are defined as part of sequence $values$. $Tm_{Enum}$ is defined as:
\begin{align*}
Class =\ &\{\} \\
Enum =\ &\{name\} \\
UserDataType =\ &\{\} \\
Field =\ &\{\} \\
\mathrm{FieldSig} =\ &\{\} \\
EnumValue =\ &\{ (name, v) \mid v \in values \} \\
Inh =\ &\{\} \\
Prop =\ &\{\} \\
Constant =\ &\{\} \\
\mathrm{ConstType} =\ &\{\}
\end{align*}
\isabellelref{tmod_enum}{Ecore-GROOVE-Mapping-Library.EnumType}
\end{defin}

\begin{thm}[Correctness of $Tm_{Enum}$]
\label{defin:library_of_transformations:type_level_transformations:enumeration_types:tmod_enum_correct}
$Tm_{Subclass}$ (\cref{defin:library_of_transformations:type_level_transformations:enumeration_types:tmod_enum}) is a consistent type model in the sense of \cref{defin:formalisations:ecore_formalisation:type_models:type_model_consistency}.
\isabellelref{tmod_enum_correct}{Ecore-GROOVE-Mapping-Library.EnumType}
\end{thm}

A visual representation of $Tm_{Enum}$ with $.\type{Example}$ as identifier for the new enumeration type and $\type{OPTION\_A}$, $\type{OPTION\_B}$ and $\type{OPTION\_C}$ as its values can be seen in \cref{fig:library_of_transformations:type_level_transformations:enumeration_types:visualisation:ecore}. The correctness proof of $Tm_{Enum}$ is trivial, and therefore not included here. The proof can be found as part of the Isabelle validated proofs.

In order to make composing transformation functions possible, $Tm_{Enum}$ should be compatible with the type model it is combined with.

\begin{thm}[Correctness of $\mathrm{combine}(Tm, Tm_{Enum})$]
\label{defin:library_of_transformations:type_level_transformations:enumeration_types:tmod_enum_combine_correct}
Assume a type model $Tm$ that is consistent in the sense of \cref{defin:formalisations:ecore_formalisation:type_models:type_model_consistency}. Then $Tm$ is compatible with $Tm_{Enum}$ (in the sense of \cref{defin:transformation_framework:type_models_and_type_graphs:combining_type_models:compatibility}) if:
\begin{itemize}
    \item The identifier of the enumeration type in $Tm_{Enum}$ is not yet an identifier for a class, enumeration type or user-defined data type in $Tm$;
    \item The identifier of the enumeration type in $Tm_{Enum}$ is not in the namespace of any class, enumeration type or user-defined data type in $Tm$;
    \item None of the identifiers in any class, enumeration type or user-defined data type in $Tm$ is in the namespace of the enumeration type in $Tm_{Enum}$.
\end{itemize}
\isabellelref{tmod_enum_combine_correct}{Ecore-GROOVE-Mapping-Library.EnumType}
\end{thm}

\begin{proof}
Use \cref{defin:transformation_framework:type_models_and_type_graphs:combining_type_models:tmod_combine_merge_correct}. It is possible to show that all assumptions hold. Now we have shown that $\mathrm{combine}(Tm, Tm_{Enum})$ is consistent in the sense of \cref{defin:formalisations:ecore_formalisation:type_models:type_model_consistency}.
\end{proof}

The definitions and theorems for a regular subclass within Ecore are now complete.

\subsubsection{Encoding as node type}

A possible encoding for enumeration types in Ecore is using node types in GROOVE. In this case, the enumeration type itself is transformed into an abstract node type. Each value of the enumeration type is converted to its own node type, extending the abstract node type. The encoding corresponding to $Tm_{Enum}$ can then be represented as $TG_{EnumNodes}$, defined in the following definition:

\begin{defin}[Type graph $TG_{EnumNodes}$]
\label{defin:library_of_transformations:type_level_transformations:enumeration_types:tg_enum_as_node_types}
Let $TG_{EnumNodes}$ be a type graph containing multiple node types. The first node type encodes the enumeration type $name$. The other node types encode the $values$ of enumeration type $name$. $TG_{EnumNodes}$ is defined as:
\begin{align*}
NT =\ &\{\mathrm{ns\_\!to\_\!list}(name)\} \cup \{ \mathrm{ns\_\!to\_\!list}(name) \append \langle v \rangle \mid v \in values \} \\
ET =\ &\{\} \\
\!\!\sqsubseteq\ =\ &\{(\mathrm{ns\_\!to\_\!list}(name), \mathrm{ns\_\!to\_\!list}(name))\}\ \cup \\&
\{(\mathrm{ns\_\!to\_\!list}(name) \append \langle v \rangle, \mathrm{ns\_\!to\_\!list}(name) \append \langle v \rangle) \mid v \in values \}\ \cup \\&
\{(\mathrm{ns\_\!to\_\!list}(name) \append \langle v \rangle, \mathrm{ns\_\!to\_\!list}(name)) \mid v \in values \} \\
abs =\ &\{\mathrm{ns\_\!to\_\!list}(name)\} \\
\mathrm{mult} =\ &\{\} \\
contains =\ &\{\}
\end{align*}
\isabellelref{tg_enum_as_node_types}{Ecore-GROOVE-Mapping-Library.EnumType}
\end{defin}

\begin{thm}[Correctness of $TG_{EnumNodes}$]
\label{defin:library_of_transformations:type_level_transformations:enumeration_types:tg_enum_as_node_types_correct}
$TG_{EnumNodes}$ (\cref{defin:library_of_transformations:type_level_transformations:enumeration_types:tg_enum_as_node_types}) is a valid type graph in the sense of \cref{defin:formalisations:groove_formalisation:type_graphs:type_graph_validity}.
\isabellelref{tg_enum_as_node_types_correct}{Ecore-GROOVE-Mapping-Library.EnumType}
\end{thm}

A visual representation of $TG_{EnumNodes}$ with $.\type{Example}$ as identifier for the encoded enumeration type and $\type{OPTION\_A}$, $\type{OPTION\_B}$ and $\type{OPTION\_C}$ as its values can be seen in \cref{fig:library_of_transformations:type_level_transformations:enumeration_types:visualisation:groove_nodes}. Please note that in this visualisation, the sequences are concatenated using the dollar sign $\$$. The correctness proof of $TG_{EnumNodes}$ is trivial, and therefore not included here. The proof can be found as part of the Isabelle validated proofs.

In order to make composing transformation functions possible, $TG_{EnumNodes}$ should be compatible with the type graph it is combined with.

\begin{thm}[Correctness of $\mathrm{combine}(TG, TG_{EnumNodes})$]
\label{defin:library_of_transformations:type_level_transformations:enumeration_types:tg_enum_as_node_types_combine_correct}
Assume a type graph $TG$ that is valid in the sense of \cref{defin:formalisations:groove_formalisation:type_graphs:type_graph_validity}. Then $TG$ is compatible with $TG_{EnumNodes}$ (in the sense of \cref{defin:transformation_framework:type_models_and_type_graphs:combining_type_graphs:compatibility}) if:
\begin{itemize}
    \item There are no shared node types between $TG_{EnumNodes}$ and $TG$.
\end{itemize}
\isabellelref{tg_enum_as_node_types_combine_correct}{Ecore-GROOVE-Mapping-Library.EnumType}
\end{thm}

\begin{proof}
Use \cref{defin:transformation_framework:type_models_and_type_graphs:combining_type_graphs:tg_combine_merge_correct}. It is possible to show that all assumptions hold. Now we have shown that $\mathrm{combine}(TG, TG_{EnumNodes})$ is valid in the sense of \cref{defin:formalisations:groove_formalisation:type_graphs:type_graph_validity}.
\end{proof}

The next definitions define the transformation function from $Tm_{Enum}$ to $TG_{EnumNodes}$:

\begin{defin}[Transformation function $f_{EnumNodes}$]
\label{defin:library_of_transformations:type_level_transformations:enumeration_types:tmod_enum_to_tg_enum_as_node_types}
The transformation function $f_{EnumNodes}(Tm)$ is defined as:
\begin{align*}
NT =\ &\{\mathrm{ns\_\!to\_\!list}(e) \mid e \in Enum_{Tm}\} \cup \{\mathrm{ns\_\!to\_\!list}(e) \append \langle v \rangle \mid (e, v) \in EnumValue_{Tm}\} \\
ET =\ &\{\} \\
\!\!\sqsubseteq\ =\ &\{(\mathrm{ns\_\!to\_\!list}(e_1), \mathrm{ns\_\!to\_\!list}(e_2)) \mid e_1 \in Enum_{Tm} \land e_2 \in Enum_{Tm} \}\ \cup \\&
\{(\mathrm{ns\_\!to\_\!list}(i) \append \langle j \rangle, \mathrm{ns\_\!to\_\!list}(i) \append \langle j \rangle) \mid (i, j) \in EnumValue_{Tm} \}\ \cup \\&
\{(\mathrm{ns\_\!to\_\!list}(i) \append \langle j \rangle, \mathrm{ns\_\!to\_\!list}(e)) \mid (i, j) \in EnumValue_{Tm} \land e \in Enum_{Tm} \} \\
abs =\ &\{\} \\
\mathrm{mult} =\ &\{\} \\
contains =\ &\{\}
\end{align*}
\isabellelref{tmod_enum_to_tg_enum_as_node_types}{Ecore-GROOVE-Mapping-Library.EnumType}
\end{defin}

\begin{thm}[Correctness of $f_{EnumNodes}$]
\label{defin:library_of_transformations:type_level_transformations:enumeration_types:tmod_enum_to_tg_enum_as_node_types_func}
$f_{EnumNodes}(Tm)$ (\cref{defin:library_of_transformations:type_level_transformations:enumeration_types:tmod_enum_to_tg_enum_as_node_types}) is a valid transformation function in the sense of \cref{defin:transformation_framework:type_models_and_type_graphs:combining_transformation_functions:transformation_function_type_model_type_graph} transforming $Tm_{Enum}$ into $TG_{EnumNodes}$.
\isabellelref{tmod_enum_to_tg_enum_as_node_types_func}{Ecore-GROOVE-Mapping-Library.EnumType}
\end{thm}

The proof of the correctness of $f_{EnumNodes}$ will not be included here. Instead, it can be found in the validated Isabelle theories.

Finally, to complete the transformation, the transformation function that transforms $TG_{EnumNodes}$ into $Tm_{Enum}$ is defined:

\begin{defin}[Transformation function $f'_{EnumNodes}$]
\label{defin:library_of_transformations:type_level_transformations:enumeration_types:tg_enum_as_node_types_to_tmod_enum}
The transformation function $f'_{EnumNodes}(TG, name)$ is defined as:
\begin{align*}
Class =\ &\{\} \\
Enum =\ &\{\mathrm{list\_\!to\_\!ns}(n) \mid n \in NT_{TG} \land n = \mathrm{id\_\!to\_\!name}(name)\} \\
UserDataType =\ &\{\} \\
Field =\ &\{\} \\
\mathrm{FieldSig} =\ &\{\} \\
EnumValue =\ &\{(\mathrm{list\_\!to\_\!ns}(e), v) \mid e \append \langle v \rangle \in NT_{TG} \land e \append \langle v \rangle \neq \mathrm{id\_\!to\_\!name}(name) \} \\
Inh =\ &\{\} \\
Prop =\ &\{\} \\
Constant =\ &\{\} \\
\mathrm{ConstType} =\ &\{\}
\end{align*}
\isabellelref{tg_enum_as_node_types_to_tmod_enum}{Ecore-GROOVE-Mapping-Library.EnumType}
\end{defin}

\begin{thm}[Correctness of $f'_{EnumNodes}$]
\label{defin:library_of_transformations:type_level_transformations:enumeration_types:tg_enum_as_node_types_to_tmod_enum_func}
$f'_{EnumNodes}(TG, name)$ (\cref{defin:library_of_transformations:type_level_transformations:enumeration_types:tg_enum_as_node_types_to_tmod_enum}) is a valid transformation function in the sense of \cref{defin:transformation_framework:type_models_and_type_graphs:combining_transformation_functions:transformation_function_type_graph_type_model} transforming $TG_{EnumNodes}$ into $Tm_{Enum}$.
\isabellelref{tg_enum_as_node_types_to_tmod_enum_func}{Ecore-GROOVE-Mapping-Library.EnumType}
\end{thm}

Once more, the correctness proof is not included here but can be found in the validated Isabelle proofs of this thesis.

\subsubsection{Encoding as flags}

Another possible encoding for enumeration types in Ecore is using flags in GROOVE. In this case, the enumeration type itself is transformed into a regular node type. Each value of the enumeration type is converted to a flag on this node type. The encoding corresponding to $Tm_{Enum}$ can then be represented as $TG_{EnumFlags}$, defined in the following definition:

\begin{defin}[Type graph $TG_{EnumFlags}$]
\label{defin:library_of_transformations:type_level_transformations:enumeration_types:tg_enum_as_flags}
Let $TG_{EnumFlags}$ be a type graph containing a single node type which encodes the enumeration type $name$. The flags on the node type of $name$ encode the different $values$. $TG_{EnumFlags}$ is defined as:
\begin{align*}
NT =\ &\{\mathrm{ns\_\!to\_\!list}(name)\} \\
ET =\ &\{ (\mathrm{ns\_\!to\_\!list}(name), \langle v \rangle, \mathrm{ns\_\!to\_\!list}(name)) \mid v \in values \}\\
\!\!\sqsubseteq\ =\ &\{(\mathrm{ns\_\!to\_\!list}(name), \mathrm{ns\_\!to\_\!list}(name))\} \\
abs =\ &\{\} \\
\mathrm{mult}(e) =\ &\begin{cases}
    (0..1, 0..1) &\mathrm{if}\ e \in ET_{TG_{EnumFlags}}
\end{cases}\\
contains =\ &\{\}
\end{align*}
\isabellelref{tg_enum_as_flags}{Ecore-GROOVE-Mapping-Library.EnumType}
\end{defin}

\begin{thm}[Correctness of $TG_{EnumFlags}$]
\label{defin:library_of_transformations:type_level_transformations:enumeration_types:tg_enum_as_flags_correct}
$TG_{EnumFlags}$ (\cref{defin:library_of_transformations:type_level_transformations:enumeration_types:tg_enum_as_flags}) is a valid type graph in the sense of \cref{defin:formalisations:groove_formalisation:type_graphs:type_graph_validity}.
\isabellelref{tg_enum_as_flags_correct}{Ecore-GROOVE-Mapping-Library.EnumType}
\end{thm}

A visual representation of $TG_{EnumFlags}$ with $.\type{Example}$ as identifier for the encoded enumeration type and $\type{OPTION\_A}$, $\type{OPTION\_B}$ and $\type{OPTION\_C}$ as its values can be seen in \cref{fig:library_of_transformations:type_level_transformations:enumeration_types:visualisation:groove_flags}. The correctness proof of $TG_{EnumFlags}$ is trivial, and therefore not included here. The proof can be found as part of the Isabelle validated proofs.

In order to make composing transformation functions possible, $TG_{EnumFlags}$ should be compatible with the type graph it is combined with.

\begin{thm}[Correctness of $\mathrm{combine}(TG, TG_{EnumFlags})$]
\label{defin:library_of_transformations:type_level_transformations:enumeration_types:tg_enum_as_flags_combine_correct}
Assume a type graph $TG$ that is valid in the sense of \cref{defin:formalisations:groove_formalisation:type_graphs:type_graph_validity}. Then $TG$ is compatible with $TG_{EnumFlags}$ (in the sense of \cref{defin:transformation_framework:type_models_and_type_graphs:combining_type_graphs:compatibility}) if:
\begin{itemize}
    \item There are no shared node types between $TG_{EnumFlags}$ and $TG$.
\end{itemize}
\isabellelref{tg_enum_as_flags_combine_correct}{Ecore-GROOVE-Mapping-Library.EnumType}
\end{thm}

\begin{proof}
Use \cref{defin:transformation_framework:type_models_and_type_graphs:combining_type_graphs:tg_combine_merge_correct}. It is possible to show that all assumptions hold. Now we have shown that $\mathrm{combine}(TG, TG_{EnumFlags})$ is valid in the sense of \cref{defin:formalisations:groove_formalisation:type_graphs:type_graph_validity}.
\end{proof}

The next definitions define the transformation function from $Tm_{Enum}$ to $TG_{EnumFlags}$:

\begin{defin}[Transformation function $f_{EnumFlags}$]
\label{defin:library_of_transformations:type_level_transformations:enumeration_types:tmod_enum_to_tg_enum_as_flags}
The transformation function $f_{EnumFlags}(Tm)$ is defined as:
\begin{align*}
NT =\ &\{\mathrm{ns\_\!to\_\!list}(e) \mid e \in Enum_{Tm}\} \\
ET =\ &\{(\mathrm{ns\_\!to\_\!list}(e), v, \mathrm{ns\_\!to\_\!list}(e)) \mid (e, v) \in EnumValue_{Tm}\} \\
\!\!\sqsubseteq\ =\ &\{(\mathrm{ns\_\!to\_\!list}(e_1), \mathrm{ns\_\!to\_\!list}(e_2)) \mid e_1 \in Enum_{Tm} \land e_2 \in Enum_{Tm} \} \\
abs =\ &\{\} \\
\mathrm{mult}(e) =\ &\begin{cases}
    (0..1, 0..1) &\mathrm{if}\ e \in \{(\mathrm{ns\_\!to\_\!list}(n), v, \mathrm{ns\_\!to\_\!list}(n)) \mid (n, v) \in EnumValue_{Tm}\}
\end{cases}\\
contains =\ &\{\}
\end{align*}
\isabellelref{tmod_enum_to_tg_enum_as_flags}{Ecore-GROOVE-Mapping-Library.EnumType}
\end{defin}

\begin{thm}[Correctness of $f_{EnumFlags}$]
\label{defin:library_of_transformations:type_level_transformations:enumeration_types:tmod_enum_to_tg_enum_as_flags_func}
$f_{EnumFlags}(Tm)$ (\cref{defin:library_of_transformations:type_level_transformations:enumeration_types:tmod_enum_to_tg_enum_as_flags}) is a valid transformation function in the sense of \cref{defin:transformation_framework:type_models_and_type_graphs:combining_transformation_functions:transformation_function_type_model_type_graph} transforming $Tm_{Enum}$ into $TG_{EnumFlags}$.
\isabellelref{tmod_enum_to_tg_enum_as_flags_func}{Ecore-GROOVE-Mapping-Library.EnumType}
\end{thm}

The proof of the correctness of $f_{EnumFlags}$ will not be included here. Instead, it can be found in the validated Isabelle theories.

Finally, to complete the transformation, the transformation function that transforms $TG_{EnumFlags}$ into $Tm_{Enum}$ is defined:

\begin{defin}[Transformation function $f'_{EnumFlags}$]
\label{defin:library_of_transformations:type_level_transformations:enumeration_types:tg_enum_as_flags_to_tmod_enum}
The transformation function $f'_{EnumFlags}(TG)$ is defined as:
\begin{align*}
Class =\ &\{\} \\
Enum =\ &\{\mathrm{list\_\!to\_\!ns}(n) \mid n \in NT_{TG}\} \\
UserDataType =\ &\{\} \\
Field =\ &\{\} \\
\mathrm{FieldSig} =\ &\{\} \\
EnumValue =\ &\{(\mathrm{list\_\!to\_\!ns}(e), v) \mid (e, v, e) \in ET_{TG} \} \\
Inh =\ &\{\} \\
Prop =\ &\{\} \\
Constant =\ &\{\} \\
\mathrm{ConstType} =\ &\{\}
\end{align*}
\isabellelref{tg_enum_as_flags_to_tmod_enum}{Ecore-GROOVE-Mapping-Library.EnumType}
\end{defin}

\begin{thm}[Correctness of $f'_{EnumNodes}$]
\label{defin:library_of_transformations:type_level_transformations:enumeration_types:tg_enum_as_flags_to_tmod_enum_func}
$f'_{EnumFlags}(TG)$ (\cref{defin:library_of_transformations:type_level_transformations:enumeration_types:tg_enum_as_flags_to_tmod_enum}) is a valid transformation function in the sense of \cref{defin:transformation_framework:type_models_and_type_graphs:combining_transformation_functions:transformation_function_type_graph_type_model} transforming $TG_{EnumFlags}$ into $Tm_{Enum}$.
\isabellelref{tg_enum_as_flags_to_tmod_enum_func}{Ecore-GROOVE-Mapping-Library.EnumType}
\end{thm}

Once more, the correctness proof is not included here but can be found in the validated Isabelle proofs of this thesis.


\documentclass[12pt]{article}
\usepackage{psfig}
\usepackage{fullpage}

% bold math italic font
\newcommand{\mbf}[1]{\mbox{\boldmath $#1$}}

% symbol used for sqrt(-1)
\newcommand{\Ci}{\ensuremath{i}}

\newcommand{\var}{{\rm var}}
\newcommand{\trace}{{\rm tr}}

\newcommand{\Rotation}{{\bf R}}
\newcommand{\Boost}{{\bf B}}

\newcommand{\vRotation}[1][n]{\ensuremath{\Rotation_{\mbfs{\hat #1}}}}
\newcommand{\vBoost}[1][m]{\ensuremath{\Boost_{\mbfs{\hat #1}}}}

\newcommand{\rotat}{\ensuremath{\vRotation(\phi)}}
\newcommand{\boost}{\ensuremath{\vBoost(\beta)}}

\newcommand{\pauli}[1]{\ensuremath{ {\mbf{\sigma}}_{#1} }}

\begin{document}

\section{Introduction}

This is a quick reference for the Measurement and Error Analysis
Library (MEAL).  The classes defined within the {\tt MEAL} namespace
implement a general-purpose library for performing non-linear
least-squares and first-order error propagation.

\section{Function Characteristics}

A mathematical function or expression is characterized by its return
type and input variables; a distinction is made between function
parameters, ${\mbf a}=(a_0, a_1, ... , a_N)$ and independent
variables, or arguments, ${\mbf x}=(x_0, x_1, ... , x_M)$.  Parameters
are double-precision floating point values that can vary freely during
modeling.  Arguments have arbitrary type and cannot be treated as free
variables during modeling.

The parameter and argument access interface is defined by the {\tt
Function} base class, and the return type is defined by {\em
evaluation base classes} that inherit {\tt Function}.  The evaluation
base classes define an {\tt evaluate} method that returns a result,
$f({\mbf x},{\mbf a})$, and the partial derivatives of this result
with respect to each of the parameters, $\partial f/\partial a_i$.

The behaviour of function expression classes is organized into
three categories: Parameter, Argument, and Evaluation.  These
behaviours are implemented by the children of three base classes,
each of which inherits the {\tt FunctionPolicy} base class.
The behaviour policies are mutually exclusive, and derived classes can
incorporate pre-defined behaviours by setting the appropriate
policy attribute.

\subsection{Parameter Policy}

A function expression may have an arbitary number of scalar parameters,
$\mbf{a}=(a_0, a_1, ... , a_N)$.  Each parameter has an associated
name, estimated variance, and a flag that indicates if the parameter
is free or fixed.  Parameter management and access is implemented by
children of the {\tt ParameterPolicy} base class.

\subsection{Argument Policy}

A function expression may be further parameterized by an arbitrary number
of independent variables, or arguments, ${\mbf x}=(x_0, x_1, ... ,
x_M)$.  Unlike parameters, arguments have no specified type, no
estimated variance, and can never be free.  Because they have no
specified type, the interface between a {\tt Function} and its
arguments is mediated through the {\tt Argument} and {\tt
Argument::Value} abstract base classes.  Argument management and
behaviour is implemented by children of the {\tt ArgumentPolicy} base
class.

\subsection{Evaluation Policy}

The return type of a function expression is unspecified in the
{\tt Function} base class definition.  Therefore, derived classes must
inherit an {\em evaluation base class}.  The evaluation base classes are
children of the {\tt Function} base class that define an {\tt evaluate} method
and an evaluation policy.  There are currently two evaluation base
classes:
\begin{itemize}
\item {\tt Scalar} - returns a scalar (double-precision) value
\item {\tt Complex2} - returns a $2\times2$ complex (double-precision) matrix
\end{itemize}
In addition, a number of template classes, known as {\tt Rules},
implement basic rules of calculus that may be used to simplify the
computation of more complicated expressions and their partial
derivatives.  There are currently two policies for dealing with the
evaluation of a evaluation base-derived class: {\tt Cached} and {\tt
NotCached}.

\section{Modular Construction}

TO DO: Show how new functions can be built up from more basic elements.

\section{Example Usage}

\subsection{Non-linear Least-Squares Estimation}

TO DO: Document lmfit

\subsection{Error Propagation}

The {\tt Estimate} template class is very useful for storing a value
and its estimated variance.  There are also operators and functions
which enable the propagation of error estimates to derived quantities;
for example:
\begin{verbatim}
Estimate<float> y (0.596,0.0034);
Estimate<float> x (-0.83,0.0072);
Estimate<float> z = pow (y,x);
\end{verbatim}
automatically computes the variance of the new variable, {\tt z}.
However, the {\tt Estimate} template class fails when a variable
appears more than once in an expression; e.g.
\begin{verbatim}
Estimate<float> ratio = x/x;
\end{verbatim}
should yield $1\pm0$; however, the {\tt Estimate} template class does
not recognize that the numerator and denominator are the same
variable, and incorrectly sums the weighted variances.

The problem of correctly computing the partial derivatives of an
expression with respect to its variables makes use of the exact same
functionality used to generate the gradient and Hessian matrix in
non-linear least squares fitting.

A simplified interface to this functionality is implemented by the
{\tt ScalarMath} class.  {\tt ScalarMath} objects may be conveniently
initialized as a single parameter and its estimated variance using the
{\tt Estimate} template class.  As with float and double types, {\tt
ScalarMath} objects may be combined using normal arithmetic operations
and basic mathematical functions, creating {\tt Scalar} functions of
any number of parameters.  For example:
\begin{verbatim}
  MEAL::ScalarMath x (Estimate<double> (0.9587, 0.00058));
  MEAL::ScalarMath y (Estimate<double> (-0.283, 0.00034));
  cerr << "Polar angle = " << atan2 (y, x) << endl;
\end{verbatim}
yields the output
\begin{verbatim}
  Polar angle = (-0.287039 +/- 0.0189612)
\end{verbatim}

\noindent
As with any native type, the {\tt ScalarMath} class can be used as a
template argument, e.g.
\begin{verbatim}
  complex<MEAL::ScalarMath> z (Estimate<double> (0.87, 0.0041),
                               Estimate<double> (2.38, 0.0095));

  complex<MEAL::ScalarMath> w (Estimate<double> (1.74, 0.0081),
                               Estimate<double> (-.63, 0.0043));

  Jones<MEAL::ScalarMath> jones (z, conj(z),
                                 conj(w), w);
\end{verbatim}
enabling error propagation through increasingly complex expressions.

\end{document}

  \section model Function Components

  All model components that inherit the MEAL::Function abstract
  base class represent functions of an arbitrary number of variables.
  A distinction is made between independent variables, or arguments,
  \f${\bf x}=(x_0, x_1, ... , x_M)\f$, and model parameters, \f${\bf
  a}=(a_0, a_1, ... , a_N)\f$.  Through use of the
  MEAL::Argument and MEAL::Argument::Value abstract base
  classes, model components may be constrained by one or more
  independent variables of arbitrary type.  The model parameters,
  \f${\bf a}\f$, represent double precision floating point values
  that may need to be constrained by some fitting technique.  Function
  classes should define an evaluation function that returns a result,
  \f$M\f$, and the partial derivative of this result with respect to
  each of the model parameters, \f$\partial M/\partial a_i\f$.  The
  independent variables,\f$\bf x\f$, represent known values, such as
  observing frequency and epoch, that may be used to further constrain
  a model.

  The MEAL::Function class does not define the type of value that
  it represents.  This is defined by derived types, which must define
  a type named Result and a method named evaluate:

  virtual Result evaluate (std::vector<Result>* gradient = 0) const = 0;

  The evaluate method returns a value of the type specified by Result
  and, if a pointer to a vector of Result is passed as the first
  argument, the vector will return the gradient of the return value
  with respect to the model parameters.

  The Return type and evaluate method are implemented by two main
  classes of MEAL::Function derived components:

  <UL>
  <LI> MEAL::Scalar - a scalar function,
  \f$f({\bf a}; {\bf x})\f$, such as the MEAL::Polynomial
  <LI> MEAL::Complex2 - a complex 2x2 matrix function,
  \f$J({\bf a}; {\bf x})\f$, such as the MEAL::Coherency matrix
  and the MEAL::Rotation transformation.
  </UL>

  \subsection calculus Partial Derivatives

  A number of template classes may be used to simplify the modular
  construction of more complicated functions.  These templates
  implement the following basic rules of differentiation:

  <UL>

  <LI> MEAL::ChainRule - an arbitrary function in which
  one or more parameters is set equal to the ordinate of a
  MEAL::Scalar function

  <LI> MEAL::BinaryRule - an associative binary operation, such
  as the sum (MEAL::SumRule) or product
  (MEAL::ProductRule).

  </UL>


\documentclass{article}
\usepackage{amsmath}

\begin{document}

\section{ Field Variables }
\begin{tabular}{|c|c|c|}
\hline
Symbol & SILO variable name & description \\
\hline
$\rho_i$ & rho\_1, rho\_2, rho\_3, etc. & ith density fraction. \\
$s_i$ & sx, sy, sz & inertial frame momentum \\
$z_i$ & zx, zy, zz & inertial frame spin momentum relative to cell center \\
$g_i$ & gx, gy, gz & gravitational acceleration \\
$\phi$ & phi & gravitational potential \\
$E$ & egas & kinetic + internal energy density \\
$\tau$ & tau & entropy tracer \\
\hline
\end{tabular}

\section{ Other Variable}

\begin{tabular}{|c|c|c|}
\hline
Symbol & SILO variable name & description \\
\hline
$\mu_i$ & atomic\_mass[i-1]  & atomic mass number of ith fraction \\
$Z_i$ & atomic\_number[i-1]  & electron number of ith fraction \\
$X$ & X[i-1] & hydrogen mass fraction of each species \\
$Z$ & Z[i-1] & metallicity of each species \\
$\Omega$ & omega & rotation frequency of the grid \\
\hline
\end{tabular}

\begin{tabular}{|c|c|}
\hline
version           & version number for this SILO file \\
code\_to\_g       & units used to convert code mass units to grams \\
code\_to\_s       & units used to convert code time units to seconds\\
code\_to\_cm      & units used to convert code length units to centimeters \\
n\_speces         & number of species, rho\_1, rho\_2, etc. \\
eos               & equation of state 0 = ideal 1 = Segretain \\
gravity           & true if gravity module is enabled \\
hydro             & true if hydro module is enabled \\
radiation         & true if radiation module is enabled \\
output\_frequency & time between outputs - for binary systems this is in \\
                  & units of orbital periods \\
problem           & problem specification (sod, dwd, etc. ) \\
refinment\_floor  & refinemnt density floor in code units \\
cgs\_time         & physical time of output from t=0 in seconds \\
rotational\_time  & time in number of orbits \\
xscale            & the length scale of the grid \\
hostname          & name of the machine this file was produced on \\
node\_list        & list of all nodes \\
node\_positions   & position of each node in the space filling curve \\
node\_count       & total number of nodes in octree \\
leaf\_count       & total number of SILO leaves, this may be less than the \\
                  & total number of octree leaves if compression is on \\
timestamp         & time the file was written \\
epoch             & starts at 0 and is incremented by one for each restart \\
                  & since t = 0 \\
locality\_count   & number of localities \\
thread\_count     & total number of threads \\
step\_count       & total number of steps \\
time\_elapsed     & time in seconds from either startup or the last output \\
                  & to the current output \\
steps\_elapsed    & number of steps from either startup or the last output \\
                  & to the current output  \\
\hline
\end{tabular}

\section{Derived Expressions}

total mass density
\begin{equation}
\rho := \Sigma_{i=1}^N \rho_i
\end{equation}

x - velocity relative to grid
\begin{equation}
v_x  := \frac{s_x}{\rho} + y \Omega
\end{equation}

y - velocity relative to grid
\begin{equation}
v_y  := \frac{s_y}{\rho} - x \Omega
\end{equation}

z - velocity relative to grid
\begin{equation}
v_z  := \frac{s_z}{\rho}
\end{equation}

\begin{equation}
\end{equation}

internal gas energy density
\begin{equation}
s^2  :=  {s_x}^2 + {s_y}^2 + {s_z}^2
e    :=  \begin{cases}
       E - \frac{1}{2} \frac{s^2}{\rho} & \text{if } E - \frac{1}{2} \frac{s^2}{\rho} > 0.001 E \\
       \tau^\gamma & \text{else} \\
     \end{cases}
\end{equation}

number density of ith fraction (ions + electrons)
\begin{equation}
n_i := \frac{\rho_i}{\mu_i m_H} \left ( 1 + Z_i \right )
\end{equation}

\begin{equation}
\gamma := \frac{5}{3}
\end{equation}

total number density
\begin{equation}
n := \Sigma_{i=1}^N  n_i
\end{equation}

temperature
\begin{equation}
T := \frac{1}{\gamma-1} \frac{e}{n}
\end{equation}

pressure
\begin{equation}
P := \left(\gamma-1\right) e
\end{equation}

\end{document}


\subsection{User-defined data types}
\label{subsec:library_of_transformations:instance_level_transformations:user_defined_data_types}

In this section, the instance level transformation corresponding to the type level transformation of user-defined data types is discussed. The type level transformation of user-defined data types can be found in \cref{subsec:library_of_transformations:type_level_transformations:user_defined_data_types}.

This definition does not actually introduce values for user-defined data types. This is done upon instantiating the type via a field. Therefore, an empty instance model and empty instance graph will be used for completeness.

First, the corresponding instance model is introduced.

\begin{defin}[Instance model $Im_{UserType}$]
\label{defin:library_of_transformations:instance_level_transformations:user_defined_data_types:imod_userdatatype}
Let $Im_{UserType}$ be the empty instance model $Im_\epsilon$ (\cref{defin:transformation_framework:instance_models_and_instance_graphs:combining_instance_models:empty_instance_model}), except that it is typed by the type model $Tm_{UserType}$ (\cref{defin:library_of_transformations:type_level_transformations:user_defined_data_types:tmod_userdatatype}).
\isabellelref{imod_userdatatype}{Ecore-GROOVE-Mapping-Library.UserDataTypeInstance}
\end{defin}

\begin{thm}[Correctness of $Im_{UserType}$]
\label{defin:library_of_transformations:instance_level_transformations:user_defined_data_types:imod_userdatatype_correct}
$Im_{UserType}$ (\cref{defin:library_of_transformations:instance_level_transformations:user_defined_data_types:imod_userdatatype}) is a valid instance model in the sense of \cref{defin:formalisations:ecore_formalisation:instance_models:model_validity}.
\isabellelref{imod_userdatatype_correct}{Ecore-GROOVE-Mapping-Library.UserDataTypeInstance}
\end{thm}

Since $Im_{UserType}$ does not define any objects, there is no need for a visual representation. However, in order to make composing transformation functions possible, $Im_{UserType}$ should still be compatible with the instance model it is combined with.

\begin{thm}[Correctness of $\mathrm{combine}(Im, Im_{UserType})$]
\label{defin:library_of_transformations:instance_level_transformations:user_defined_data_types:imod_userdatatype_combine_correct}
Assume an instance model $Im$ that is valid in the sense of \cref{defin:formalisations:ecore_formalisation:instance_models:model_validity}. Then $Im$ is compatible with $Im_{UserType}$ (in the sense of \cref{defin:transformation_framework:instance_models_and_instance_graphs:combining_instance_models:compatibility}) if:
\begin{itemize}
    \item All requirements of \cref{defin:library_of_transformations:type_level_transformations:user_defined_data_types:tmod_userdatatype_combine_correct} are met, to ensure the combination of the corresponding type models is valid.
\end{itemize}
\isabellelref{imod_userdatatype_combine_correct}{Ecore-GROOVE-Mapping-Library.UserDataTypeInstance}
\end{thm}

\begin{proof}
Use \cref{defin:transformation_framework:instance_models_and_instance_graphs:combining_instance_models:imod_combine_merge_correct}. It is possible to show that all assumptions hold. Now we have shown that $\mathrm{combine}(Im, Im_{UserType})$ is consistent in the sense of \cref{defin:formalisations:ecore_formalisation:instance_models:model_validity}.
\end{proof}

The definitions and theorems for the Ecore instance model corresponding to $Tm_{UserType}$ are now complete.

\subsubsection{The node type encoding}

As has been shown earlier, an possible encoding for user-defined data types is by introducing a node type. This has been done in $TG_{UserType}$. Like the Ecore instance model, the GROOVE instance graph is also empty, because the values for the type are not instantiated now. This gives rise to $IG_{UserType}$, which is defined as follows:

\begin{defin}[Instance graph $IG_{UserType}$]
\label{defin:library_of_transformations:instance_level_transformations:user_defined_data_types:ig_userdatatype_as_node_type}
Let $IG_{UserType}$ be the empty instance graph $IG_\epsilon$ (\cref{defin:transformation_framework:instance_models_and_instance_graphs:combining_instance_graphs:empty_instance_graph}), except that it is typed by the type graph $TG_{UserType}$ (\cref{defin:library_of_transformations:type_level_transformations:user_defined_data_types:tg_userdatatype_as_node_type}).
\isabellelref{ig_userdatatype_as_node_type}{Ecore-GROOVE-Mapping-Library.UserDataTypeInstance}
\end{defin}

\begin{thm}[Correctness of $IG_{UserType}$]
\label{defin:library_of_transformations:instance_level_transformations:user_defined_data_types:ig_class_as_node_type_correct}
$IG_{UserType}$ (\cref{defin:library_of_transformations:instance_level_transformations:user_defined_data_types:ig_userdatatype_as_node_type}) is a valid instance graph in the sense of \cref{defin:formalisations:groove_formalisation:instance_graphs:instance_graph_validity}.
\isabellelref{ig_userdatatype_as_node_type_correct}{Ecore-GROOVE-Mapping-Library.UserDataTypeInstance}
\end{thm}

In order to make composing transformation functions possible, $IG_{UserType}$ should be compatible with the instance graph it is combined with.

\begin{thm}[Correctness of $\mathrm{combine}(IG, IG_{UserType})$]
\label{defin:library_of_transformations:instance_level_transformations:user_defined_data_types:ig_userdatatype_as_node_type_combine_correct}
Assume an instance graph $IG$ that is valid in the sense of \cref{defin:formalisations:groove_formalisation:instance_graphs:instance_graph_validity}. Then $IG$ is compatible with $IG_{UserType}$ (in the sense of \cref{defin:transformation_framework:instance_models_and_instance_graphs:combining_instance_graphs:compatibility}) if:
\begin{itemize}
    \item All requirements of \cref{defin:library_of_transformations:type_level_transformations:user_defined_data_types:tg_userdatatype_as_node_type_combine_correct} are met, to ensure the combination of the corresponding type graphs is valid.
\end{itemize}
\isabellelref{ig_userdatatype_as_node_type_combine_correct}{Ecore-GROOVE-Mapping-Library.UserDataTypeInstance}
\end{thm}

\begin{proof}
Use \cref{defin:transformation_framework:instance_models_and_instance_graphs:combining_instance_graphs:ig_combine_merge_correct}. It is possible to show that all assumptions hold. Now we have shown that $\mathrm{combine}(IG, IG_{UserType})$ is valid in the sense of \cref{defin:formalisations:groove_formalisation:instance_graphs:instance_graph_validity}.
\end{proof}

The next definitions define the transformation function from $Im_{UserType}$ to $IG_{UserType}$:

\begin{defin}[Transformation function $f_{UserType}$]
\label{defin:library_of_transformations:instance_level_transformations:user_defined_data_types:imod_userdatatype_to_ig_userdatatype_as_node_type}
The transformation function $f_{UserType}(Im)$ is defined as the function that always outputs the empty instance graph $IG_\epsilon$ (\cref{defin:transformation_framework:instance_models_and_instance_graphs:combining_instance_graphs:empty_instance_graph}), except that it is typed by $TG_{UserType}$.
\isabellelref{imod_userdatatype_to_ig_userdatatype_as_node_type}{Ecore-GROOVE-Mapping-Library.UserDataTypeInstance}
\end{defin}

\begin{thm}[Correctness of $f_{UserType}$]
\label{defin:library_of_transformations:instance_level_transformations:user_defined_data_types:imod_userdatatype_to_ig_userdatatype_as_node_type_func}
$f_{UserType}(Im)$ (\cref{defin:library_of_transformations:instance_level_transformations:user_defined_data_types:imod_userdatatype_to_ig_userdatatype_as_node_type}) is a valid transformation function in the sense of \cref{defin:transformation_framework:instance_models_and_instance_graphs:combining_transformation_functions:transformation_function_instance_model_instance_graph} transforming $Im_{UserType}$ into $IG_{UserType}$.
\isabellelref{imod_userdatatype_to_ig_userdatatype_as_node_type_func}{Ecore-GROOVE-Mapping-Library.UserDataTypeInstance}
\end{thm}

The proof of the correctness of $f_{UserType}$ will not be included here. Instead, it can be found in the validated Isabelle theories. Obviously, the proof is trivial, as the function does not do any conversion. It does just output the empty instance model.

Finally, to complete the transformation, the transformation function that transforms $IG_{UserType}$ into $Im_{UserType}$ is defined:

\begin{defin}[Transformation function $f'_{UserType}$]
\label{defin:library_of_transformations:instance_level_transformations:user_defined_data_types:ig_userdatatype_as_node_type_to_imod_userdatatype}
The transformation function $f'_{UserType}(IG)$ is defined as the function that always outputs the empty instance model $Im_\epsilon$ (\cref{defin:transformation_framework:instance_models_and_instance_graphs:combining_instance_models:empty_instance_model}), except that it is typed by $Tm_{UserType}$.
\isabellelref{ig_userdatatype_as_node_type_to_imod_userdatatype}{Ecore-GROOVE-Mapping-Library.UserDataTypeInstance}
\end{defin}

\begin{thm}[Correctness of $f'_{UserType}$]
\label{defin:library_of_transformations:instance_level_transformations:user_defined_data_types:ig_userdatatype_as_node_type_to_imod_userdatatype_func}
$f'_{UserType}(IG)$ (\cref{defin:library_of_transformations:instance_level_transformations:user_defined_data_types:ig_userdatatype_as_node_type_to_imod_userdatatype}) is a valid transformation function in the sense of \cref{defin:transformation_framework:instance_models_and_instance_graphs:combining_transformation_functions:transformation_function_instance_graph_instance_model} transforming $IG_{UserType}$ into $Im_{UserType}$.
\isabellelref{ig_userdatatype_as_node_type_to_imod_userdatatype_func}{Ecore-GROOVE-Mapping-Library.UserDataTypeInstance}
\end{thm}

Once more, the correctness proof is not included here but can be found in the validated Isabelle proofs of this thesis.