\lab{Pandas 3: Grouping}{Pandas 3: Grouping}
\objective{
Many data sets contain categorical values that naturally sort the data into groups.
Analyzing and comparing such groups is an important part of data analysis.
In this lab we explore pandas tools for grouping data and presenting tabular data more compactly, primarily through grouby and pivot tables.
}

\section*{Groupby} % ==========================================================

The file \texttt{mammal\_sleep.csv}\footnote{Proceedings of the National Academy of Sciences, 104 (3):1051--1056, 2007.
Updates from V. M. Savage and G. B. West, with additional variables supplemented by Wikipedia.
Available in \texttt{pydataset} (with a few more columns) under the key \texttt{"msleep"}.} contains data on the sleep cycles of different mammals, classified by order, genus, species, and diet (carnivore, herbivore, omnivore, or insectivore).
The \li{"sleep_total"} column gives the total number of hours that each animal sleeps (on average) every $24$ hours.
To get an idea of how many animals sleep for how long, we start off with a histogram of the \li{"sleep_total"} column.

\begin{lstlisting}
>>> import pandas as pd
>>> from matplotlib import pyplot as plt

# Read in the data and print a few random entries.
>>> msleep = pd.read_csv("mammal_sleep.csv")
>>> msleep.sample(5)
<<      name     genus   vore         order  sleep_total  sleep_rem  sleep_cycle
51  Jaguar  Panthera  carni     Carnivora         10.4        NaN          NaN
77  Tenrec    Tenrec   omni  Afrosoricida         15.6        2.3          NaN
10    Goat     Capri  herbi  Artiodactyla          5.3        0.6          NaN
80   Genet   Genetta  carni     Carnivora          6.3        1.3          NaN
33   Human      Homo   omni      Primates          8.0        1.9          1.5>>

# Plot the distribution of the sleep_total variable.
>>> msleep.plot(kind="hist", y="sleep_total", title="Mammalian Sleep Data")
>>> plt.xlabel("Hours")
\end{lstlisting}

\begin{figure}[H] % Mammal sleep_total hist (all groups)
    \centering
    \includegraphics[width=.7\textwidth]{figures/mammal_hist.pdf}
    \caption{\li{"sleep_total"} frequencies from the mammalian sleep data set.}
    \label{fig:pandas-mammals-sleep-all}
\end{figure}

While this visualization is a good start, it doesn't provide any information about how different kinds of animals have different sleeping habits.
How long do carnivores sleep compared to herbivores?
Do mammals of the same genus have similar sleep patterns?

A powerful tool for answering these kinds of questions is the \li{groupby()} method of the pandas \li{DataFrame} class, which partitions the original \li{DataFrame} into groups based on the values in one or more columns.
The \li{groupby()} method does \textbf{not} return a new \li{DataFrame}; it returns a pandas \li{GroupBy} object, an interface for analyzing the original \li{DataFrame} by groups.

For example, the columns \li{"genus"}, \li{"vore"}, and \li{"order"} in the mammal sleep data all have a discrete number of categorical values that could be used to group the data.
Since the \li{"vore"} column has only a few unique values, we start by grouping the animals by diet.

\begin{lstlisting}
# List all of the unique values in the 'vore' column.
>>> set(msleep["vore"])
<<{nan, 'herbi', 'omni', 'carni', 'insecti'}>>

# Group the data by the 'vore' column.
>>> vores = msleep.groupby("vore")
>>> list(vores.groups)
<<['carni', 'herbi', 'insecti', 'omni']>>       # NaN values for vore were dropped.

# Get a single group and sample a few rows. Note vore='carni' in each entry.
>>> vores.get_group("carni").sample(5)
<<       name     genus   vore      order  sleep_total  sleep_rem  sleep_cycle
80    Genet   Genetta  carni  Carnivora          6.3        1.3          NaN
50    Tiger  Panthera  carni  Carnivora         15.8        NaN          NaN
8       Dog     Canis  carni  Carnivora         10.1        2.9        0.333
0   Cheetah  Acinonyx  carni  Carnivora         12.1        NaN          NaN
82  Red fox    Vulpes  carni  Carnivora          9.8        2.4        0.350>>
\end{lstlisting}

For starters, \li{groupby()} is useful for filtering a \li{DataFrame} by column values:
the command \li{df.groupby(col).get_group(value)} returns the rows of \li{df} where the entry of the \li{col} column is \li{value}.
The real advantage of \li{groupby()}, however, is how easy it makes it to compare groups of data.
Standard \li{DataFrame} methods like \li{describe()}, \li{mean()}, \li{std()}, \li{<<min>>()}, and \li{<<max>>()} all work on \li{GroupBy} objects to produce a new data frame that describes the statistics of each group.

\begin{lstlisting}
# Get averages of the numerical columns for each group.
>>> vores.mean()
<<         sleep_total  sleep_rem  sleep_cycle
vore
carni         10.379      2.290        0.373
herbi          9.509      1.367        0.418
insecti       14.940      3.525        0.161
omni          10.925      1.956        0.592>>

# Get more detailed statistics for 'sleep_total' by group.
>>> vores["sleep_total"].describe()
<<         count    mean    std  min   25%   50%     75%   max
vore
carni     19.0  10.379  4.669  2.7  6.25  10.4  13.000  19.4
herbi     32.0   9.509  4.879  1.9  4.30  10.3  14.225  16.6
insecti    5.0  14.940  5.921  8.4  8.60  18.1  19.700  19.9
omni      20.0  10.925  2.949  8.0  9.10   9.9  10.925  18.0>>
\end{lstlisting}

Multiple columns can be used simultaneously for grouping.
In this case, the \li{get_group()} method of the \li{GroupBy} object requires a tuple specifying the values for each of the grouping columns.

\begin{lstlisting}
>>> msleep_small = msleep.drop(["sleep_rem", "sleep_cycle"], axis=1)
>>> vores_orders = msleep_small.groupby(["vore", "order"])
>>> vores_orders.get_group(("carni", "Cetacea"))
<<                    name          genus   vore    order  sleep_total
30           Pilot whale  Globicephalus  carni  Cetacea          2.7
59       Common porpoise       Phocoena  carni  Cetacea          5.6
79  Bottle-nosed dolphin       Tursiops  carni  Cetacea          5.2>>
\end{lstlisting}

\subsection*{Visualizing Groups} % --------------------------------------------

There are a few ways that \li{groupby()} or similar techniques can simplify the process of visualizing groups of data.
First of all, \li{groupby()} makes it easy to visualize one group at a time.
The following visualization improve on Figure \ref{fig:pandas-mammals-sleep-all} by grouping mammals by their diets.

\begin{lstlisting}
# Plot histograms of 'sleep_total' for two separate groups.
>>> vores.get_group("carni").plot(kind="hist", y="sleep_total", legend="False",
                                                title="Carnivore Sleep Data")
>>> plt.xlabel("Hours")
>>> vores.get_group("herbi").plot(kind="hist", y="sleep_total", legend="False",
                                                title="Herbivore Sleep Data")
>>> plt.xlabel("Hours")
\end{lstlisting}

\begin{figure}[H] % Grouped mammal sleep_total histograms.
\captionsetup[subfigure]{justification=centering}
\centering
\begin{subfigure}{.495\textwidth}
    \centering
    \includegraphics[width=\textwidth]{figures/mammal_hist_carni.pdf}
\end{subfigure}
%
\begin{subfigure}{.495\textwidth}
    \centering
    \includegraphics[width=\textwidth]{figures/mammal_hist_herbi.pdf}
\end{subfigure}
\caption{\li{"sleep_total"} histograms for two groups in the mammalian sleep data set.}
\end{figure}

\begin{comment} % hist() isn't a great option from a datavis standpoint.
\begin{info}
The \li{hist()} method of the \li{DataFrame} class has a keyword \li{by} that groups data before plotting, producing one histogram per group.
This can be a very quick way to get an overview of the data in multiple groups.

\begin{lstlisting}
>>> msleep.hist("sleep_total", by="vore", sharex=True)
>>> plt.tight_layout()
\end{lstlisting}
\end{info}
\end{comment}

The statistical summaries from the \li{GroupBy} object's \li{mean()}, \li{std()}, or \li{describe()} methods also lend themselves well to certain visualizations for comparing groups.

\begin{lstlisting}
>>> vores[["sleep_total", "sleep_rem", "sleep_cycle"]].mean().plot(kind="barh",
                xerr=vores.std(), title=r"Mammallian Sleep, $\mu\pm\sigma$")
>>> plt.xlabel("Hours")
>>> plt.ylabel("Mammal Diet Classification (vore)")
\end{lstlisting}

\begin{figure}[H]
    \centering
    \includegraphics[width=.7\textwidth]{figures/mammal_bar.pdf}
\end{figure}

Box plots are well suited for comparing similar distributions.
The \li{boxplot()} method of the \li{GroupBy} class creates one subplot \textbf{per group}, plotting each of the columns as a box plot.

\begin{lstlisting}
# Use GroupBy.boxplot() to generate one box plot per group.
>>> vores.boxplot(grid=False)
>>> plt.tight_layout()
\end{lstlisting}

\begin{figure}[H]
    \centering
    \includegraphics[width=.7\textwidth]{figures/mammal_box_groups.pdf}
\end{figure}

Alternatively, the \li{boxplot()} method of the \li{DataFrame} class creates one subplot \textbf{per column}, plotting each of the columns as a box plot.
Specify the \li{by} keyword to group the data appropriately.

\begin{lstlisting}
# Use DataFrame.boxplot() to generate one box plot per column.
>>> msleep.boxplot(["sleep_total", "sleep_rem"], by="vore", grid=False)
\end{lstlisting}

\begin{figure}[H]
    \centering
    \includegraphics[width=.7\textwidth]{figures/mammal_box_cols.pdf}
\end{figure}

Like \li{groupby()}, the \li{by} argument can be a single column label or a list of column labels.
Similar methods exist for creating histograms (\li{GroupBy.hist()} and \li{DataFrame.hist()} with \li{by} keyword), but generally box plots are better for comparing multiple distributions.

\begin{problem} % More dataset visualizations.
Examine the following data sets from \li{pydataset} and answer the corresponding questions.
Use visualizations to support your conclusions.

\begin{itemize}
    \item \li{"iris"}, measurements of various species of iris flowers.
    \begin{enumerate}
        \item Which species is easiest to distinguish from the others? How?
        \item Given iris data without a species label, what strategies could you use to identify the flower's species?
    \end{enumerate}
    \item \li{"poisons"}, experimental results of three different poisons and four different treatments.
    \begin{enumerate}
        \item In general, which poison is most deadly?
        Which treatment is most effective?
        \item If you were poisoned, how would you choose the treatment if you did not know which poison it was? What if you did know which poison it was?
        \\(Hint: group the data by poison, then group each subset by treatment.)
    \end{enumerate}
    \item \li{"diamonds"}, prices and characteristics of almost 54,000 round-cut diamonds.
    \begin{enumerate}
        \item How does the color and cut of a diamond affect its price?
        \item Of the diamonds with color \li{"H"}, those with a \li{"Fair"} cut sell, on average, for a \textbf{higher} price than those with an \li{"Ideal"} (superior) cut.
        What other factors could explain this unintuitive statistic?
    \end{enumerate}
\end{itemize}
\end{problem}

\section*{Pivot Tables} % =====================================================

One of the downfalls of \li{groupby()} is that a typical \li{GroupBy} object has too much information to display coherently.
A \emph{pivot table} intelligently summarizes the results of a \li{groupby()} operation by aggregating the data in a specified way.
The standard tool for making a pivot table is the \li{pivot_table()} method of the \li{DataFrame} class.
As an example, consider the \li{"HairEyeColor"} data set from \li{pydataset}.

\begin{lstlisting}
>>> from pydataset import data
>>> hec = data("HairEyeColor")              # Load and preview the data.
>>> hec.sample(5)
<<     Hair    Eye     Sex  Freq
3     Red  Brown    Male    10
1   Black  Brown    Male    32
14  Brown  Green    Male    15
31    Red  Green  Female     7
21  Black   Blue  Female     9>>

>>> for col in ["Hair", "Eye", "Sex"]:      # Get unique values per column.
...     print("{}: {}".format(col, ", ".join(set(str(x) for x in hec[col]))))
...
Hair: Brown, Black, Blond, Red
Eye: Brown, Blue, Hazel, Green
Sex: Male, Female
\end{lstlisting}

There are several ways to group this data with \li{groupby()}.
However, since there is only one entry per unique hair-eye-sex combination, the data can be completely presented in a pivot table.

\begin{lstlisting}
>>> hec.pivot_table(values="Freq", index=["Hair", "Eye"], columns="Sex")
<<Sex          Female  Male
Hair  Eye
Black Blue        9    11
      Brown      36    32
      Green       2     3
      Hazel       5    10
Blond Blue       64    30
      Brown       4     3
      Green       8     8
      Hazel       5     5
Brown Blue       34    50
      Brown      66    53
      Green      14    15
      Hazel      29    25
Red   Blue        7    10
      Brown      16    10
      Green       7     7
      Hazel       7     7>>
\end{lstlisting}

Listing the data in this way makes it easy to locate data and compare the female and male groups.
For example, it is easy to see that brown hair is more common than red hair and that about twice as many females have blond hair and blue eyes than males.

Unlike \li{"HairEyeColor"}, many data sets have more than one entry in the data for each grouping (for example, if there were two or more rows in the original data for females with blond hair and blue eyes).
To construct a pivot table, data of similar groups must be \emph{aggregated} together in some way.
By default entries are aggregated by averaging the non-null values.
Other options include taking the min, max, standard deviation, or just counting the number of occurrences.

As an example, consider again the Titanic data set found in \texttt{titanic.csv}\footnote{There is a \lif{"Titanic"} data set in \lif{pydataset}, but it does not contain as much information as the data in \texttt{titanic.csv}.}.
For this analysis, take only the \li{"Survived"}, \li{"Pclass"}, \li{"Sex"}, \li{"Age"}, \li{"Fare"}, and \li{"Embarked"} columns, replace null age values with the average age, then drop any rows that are missing data.
To begin, we examine the average survival rate grouped by sex and passenger class.

\begin{lstlisting}
>>> titanic = pd.read_csv("titanic.csv")
>>> titanic = titanic[["Survived", "Pclass", "Sex", "Age", "Fare", "Embarked"]]
>>> titanic["Age"].fillna(titanic["Age"].mean(), inplace=True)
>>> titanic.dropna(inplace=True)

>>> titanic.pivot_table(values="Survived", index="Sex", columns="Pclass")
<<Pclass    1.0    2.0    3.0
Sex
female  0.965  0.887  0.491
male    0.341  0.146  0.152>>
\end{lstlisting}

\begin{info} % pivot_table() is a shortcut for a complicated groupby().
The \li{pivot_table()} method is just a convenient way of performing a potentially complicated \li{groupby()} operation with aggregation and some reshaping.
For example, the following code is equivalent to the previous example.

\begin{lstlisting}
>>> titanic.groupby(["Sex", "Pclass"])["Survived"].mean().unstack()
<<Pclass    1.0    2.0    3.0
Sex
female  0.965  0.887  0.491
male    0.341  0.146  0.152>>
\end{lstlisting}

The \li{stack()}, \li{unstack()}, and \li{pivot()} methods provide more advanced shaping options.
\end{info}

Among other things, this pivot table clearly shows how much more likely females were to survive than males.
To see how many entries fall into each category, or how many survived in each category, aggregate by counting or summing instead of taking the mean.

\begin{lstlisting}
# See how many entries are in each category.
>>> titanic.pivot_table(values="Survived", index="Sex", columns="Pclass",
...                     aggfunc="count")
<<Pclass  1.0  2.0  3.0
Sex
female  144  106  216
male    179  171  493>>

# See how many people from each category survived.
>>> titanic.pivot_table(values="Survived", index="Sex", columns="Pclass",
...                     aggfunc="sum")
<<Pclass    1.0   2.0    3.0
Sex
female  137.0  94.0  106.0
male     61.0  25.0   75.0>>
\end{lstlisting}

\subsection*{Discretizing Continuous Data} % ----------------------------------

So far we have examined survival rates based on sex and passenger class.
Another factor that could have played into survival is age.
Were male children as likely to die as females in general?
We can investigate this question by \emph{multi-indexing}, or pivoting on more than just two variables, by adding in another index.

In the original dataset, the \li{"Age"} column has a floating point value for the age of each passenger.
If we just added \li{"Age"} as another pivot, then the table would create a new row for \textbf{each} age present.
Instead, we partition the \li{"Age"} column into intervals with \li{pd.cut()}, thus creating a categorical that can be used for grouping.

\newpage

\begin{lstlisting}
# pd.cut() maps continuous entries to discrete intervals.
>>> pd.cut([6, 1, 2, 3, 4, 5, 6, 7], [0, 4, 8])
<<[(0, 4], (0, 4], (0, 4], (0, 4], (4, 8], (4, 8], (4, 8], (0, 4]]
Categories (2, interval[int64]): [(0, 4] < (4, 8]]>>

# Partition the passengers into 3 categories based on age.
>>> age = pd.cut(titanic['Age'], [0, 12, 18, 80])

>>> titanic.pivot_table(values="Survived", index=["Sex", age],
                        columns="Pclass", aggfunc="mean")
<<Pclass             1.0    2.0    3.0
Sex    Age
female (0, 12]   0.000  1.000  0.467
       (12, 18]  1.000  0.875  0.607
       (18, 80]  0.969  0.871  0.475
male   (0, 12]   1.000  1.000  0.343
       (12, 18]  0.500  0.000  0.081
       (18, 80]  0.322  0.093  0.143>>
\end{lstlisting}

From this table, it appears that male children (ages 0 to 12) in the 1st and 2nd class were very likely to survive, whereas those in 3rd class were much less likely to.
This clarifies the claim that males were less likely to survive than females.
However, there are a few oddities in this table: zero percent of the female children in 1st class survived, and zero percent of teenage males in second class survived.
To further investigate, count the number of entries in each group.

%
% This might seem a little odd, but if we looked at our data set again to see how many passengers fell into this category of female, 1st class, and age 0 to 12, we would find only one passenger.
% Therefore, the statistic that 0\% of female children in first class lived is misleading.

\begin{lstlisting}
>>> titanic.pivot_table(values="Survived", index=["Sex", age],
                        columns="Pclass", aggfunc="count")
<<Pclass           1.0  2.0  3.0
Sex    Age
female (0, 12]     1   13   30
       (12, 18]   12    8   28
       (18, 80]  129   85  158
male   (0, 12]     4   11   35
       (12, 18]    4   10   37
       (18, 80]  171  150  420>>
\end{lstlisting}

This table shows that there was only 1 female child in first class and only 10 male teenagers in second class, which sheds light on the previous table.

\begin{warn}
The previous pivot table brings up an important point about partitioning datasets.
The Titanic dataset includes data for about 1300 passengers, which is a somewhat reasonable sample size, but half of the groupings include less than 30 entries, which is \textbf{not} a healthy sample size for statistical analysis.
Always carefully question the numbers from pivot tables before making any conclusions.
\end{warn}

Pandas also supports multi-indexing on the columns.
As an example, consider the price of a passenger tickets.
This is another continuous feature that can be discretized with \li{pd.cut()}.
Instead, we use \li{pd.qcut()} to split the prices into 2 equal quantiles.
Some of the resulting groups are empty; to improve readability, specify \li{fill_value} as the empty string or a dash.

\begin{lstlisting}
# pd.qcut() partitions entries into equally populated intervals.
>>> pd.qcut([1, 2, 5, 6, 8, 3], 2)
<<[(0.999, 4.0], (0.999, 4.0], (4.0, 8.0], (4.0, 8.0], (4.0, 8.0], (0.999, 4.0]]
Categories (2, interval[float64]): [(0.999, 4.0] < (4.0, 8.0]]>>

# Cut the ticket price into two intervals (cheap vs expensive).
>>> fare = pd.qcut(titanic["Fare"], 2)
>>> titanic.pivot_table(values="Survived",
                        index=["Sex", age], columns=[fare, "Pclass"],
                        aggfunc="count", fill_value='-')
<<Fare            (-0.001, 14.454]          (14.454, 512.329]
Pclass                       1.0 2.0  3.0               1.0 2.0 3.0
Sex    Age
female (0, 12]                 -   -    7                 1  13  23
       (12, 18]                -   4   23                12   4   5
       (18, 80]                -  31  101               129  54  57
male   (0, 12]                 -   -    8                 4  11  27
       (12, 18]                -   5   26                 4   5  11
       (18, 80]                8  94  350               163  56  70>>
\end{lstlisting}

Not surprisingly, most of the cheap tickets went to passengers in 3rd class.
%
% It should be noted though that with datasets where NaN's occur frequently, some preprocessing needs to be done so as to get the most accurate statistics and insights about your dataset.

\begin{problem} % More Titanic analysis.
Suppose that someone claims that the city from which a passenger embarked had a strong influence on the passenger's survival rate.
Investigate this claim.
\begin{enumerate}
    \item Check the survival rates of the passengers based on where they embarked from (given in the \li{"Embarked"} column).
    \item Create a pivot table to examine survival rates based on both place of embarkment and gender.
    \item What do these tables suggest to you about the significance of where people embarked in influencing their survival rate?
    Examine the context of the problem, and explain what you think this really means.
    \item Investigate the claim further with at least two more pivot tables, exploring other criteria (e.g., class, age, etc.).
    Carefully explain your conclusions.
\end{enumerate}
\end{problem}

\newpage

\begin{problem} % More grouping visualizations / pivot tables.
Examine the following data sets from \li{pydataset} and answer the corresponding questions.
Use visualizations and/or pivot tables as appropriate to support your conclusions.
\begin{itemize}
    \item \li{"npk"}, an experiment on the effects of nitrogen (N), phosphate (P), and potassium (K) on the growth of peas.
    \begin{enumerate}
        \item Which element is most effective in general for simulating growth?
        Which is the least effective?
        \item What combination of N, P, and K is optimal? What combination is the worst?
    \end{enumerate}
    \item \li{"swiss"}, standardized fertility measures and socio-economic indicators for French-speaking provinces of Switzerland at about 1888.
    \begin{enumerate}
        \item What is the relationship in the data between fertility rates and infant mortality?
        \item How are provinces that are predominantly Catholic different from non-Catholic provinces, if at all?
        \item What factors in the data are the most important for predicting fertility?
    \end{enumerate}
    \item Examine a data set of your choice.
    Formulate simple questions about the data and hypothesize the answers to those questions.
    Demonstrate the correctness of incorrectness of each hypothesis.
    Explain your conclusions.
\end{itemize}
\end{problem}


\input{newcommands}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Mesh refinement}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{figure}[htb]
  \centering
  \includegraphics[width=15cm]{ICNSP_2011_Vay_fig1.png}
  \caption{Sketches of the implementation of mesh refinement in WarpX with the electrostatic (left) and electromagnetic (right) solvers. In both cases, the charge/current from particles are deposited at the finest levels first, then interpolated recursively to coarser levels. In the electrostatic case, the potential is calculated first at the coarsest level $L_0$, the solution interpolated to the boundaries of the refined patch $r$ at the next level $L_{1}$ and the potential calculated at $L_1$. The procedure is repeated iteratively up to the highest level.  In the electromagnetic case, the fields are computed independently on each grid and patch without interpolation at boundaries. Patches are terminated by absorbing layers (PML) to prevent the reflection of electromagnetic waves. Additional coarse patch $c$ and fine grid $a$ are needed so that the full solution is obtained by substitution on $a$ as $F_{n+1}(a)=F_{n+1}(r)+I[F_n( s )-F_{n+1}( c )]$ where $F$ is the field, and $I$ is a coarse-to-fine interpolation operator. In both cases, the field solution at a given level $L_n$ is unaffected by the solution at higher levels $L_{n+1}$ and up, allowing for mitigation of some spurious effects (see text) by providing a transition zone via extension of the patches by a few cells beyond the desired refined area (red \& orange rectangles) in which the field is interpolated onto particles from the coarser parent level only.}
  \label{fig:ESAMR}
\end{figure}

The mesh refinement methods that have been implemented in WarpX were developed following the following principles: i) avoidance of spurious effects from mesh refinement, or minimization of such effects; ii) user controllability of the spurious effects' relative magnitude; iii) simplicity of implementation. The two main generic issues that were identified are: a) spurious self-force on macroparticles close to the mesh refinement interface \cite{Vaylpb2002,Colellajcp2010}; b) reflection (and possible amplification) of short wavelength electromagnetic waves at the mesh refinement interface \cite{Vayjcp01}. The two effects are due to the loss of translation invariance introduced by the asymmetry of the grid on each side of the mesh refinement interface.

In addition, for some implementations where the field that is computed at a given level is affected by the solution at finer levels, there are cases where the procedure violates the integral of Gauss' Law around the refined patch, leading to long range errors \cite{Vaylpb2002,Colellajcp2010}. As will be shown below, in the procedure that has been developed in WarpX, the field at a given refinement level is not affected by the solution at finer levels, and is thus not affected by this type of error.

\subsection{Electrostatic}
A cornerstone of the Particle-In-Cell method is that assuming a particle lying in a hypothetical infinite grid, then if the grid is regular and symmetrical, and if the order of field gathering matches the order of charge (or current) deposition, then there is no self-force of the particle acting on itself: a) anywhere if using the so-called ``momentum conserving'' gathering scheme; b) on average within one cell if using the ``energy conserving'' gathering scheme \cite{Birdsalllangdon}. A breaking of the regularity and/or symmetry in the grid, whether it is from the use of irregular meshes or mesh refinement, and whether one uses finite difference, finite volume or finite elements, results in a net spurious self-force (which does not average to zero over one cell)  for a macroparticle close to the point of irregularity (mesh refinement interface for the current purpose) \cite{Vaylpb2002,Colellajcp2010}.

A sketch of the implementation of mesh refinement in WarpX is given in Figure~\ref{fig:ESAMR} (left). Given the solution of the electric potential at a refinement level $L_n$, it is interpolated onto the boundaries of the grid patch(es) at the next refined level $L_{n+1}$. The electric potential is then computed at level $L_{n+1}$ by solving the Poisson equation. This procedure necessitates the knowledge of the charge density at every level of refinement. For efficiency, the macroparticle charge is deposited on the highest level patch that contains them, and the charge density of each patch is added recursively to lower levels, down to the lowest.

\begin{figure}[htb]
  \centering
  \includegraphics[width=15cm]{ICNSP_2011_Vay_fig2.png}
  \caption{Position history of one charged particle attracted by its image induced by a nearby metallic (dirichlet) boundary. The particle is initialized at rest. Without refinement patch (reference case), the particle is accelerated by its image, is reflected specularly at the wall, then decelerates until it reaches its initial position at rest. If the particle is initialized inside a refinement patch, the particle is initially accelerated toward the wall but is spuriously reflected before it reaches the boundary of the patch whether using the method implemented in WarpX or the MC method. Providing a surrounding transition region 2 or 4 cells wide in which the potential is interpolated from the parent coarse solution reduces significantly the effect of the spurious self-force. }
  \label{fig:ESselfforce}
\end{figure}
The presence of the self-force is illustrated on a simple test case that was introduced in \cite{Vaylpb2002} and also used in \cite{Colellajcp2010}: a single macroparticle is initialized at rest within a single refinement patch four cells away from the patch refinement boundary. The patch at level $L_1$ has $32\times32$ cells and is centered relative to the lowest $64\times64$ grid at level $L_0$ (``main grid''), while the macroparticle is centered in one direction but not in the other. The boundaries of the main grid are perfectly conducting, so that the macroparticle is attracted to the closest wall by its image. Specular reflection is applied when the particle reaches the boundary so that the motion is cyclic. The test was performed with WarpX using either linear or quadratic interpolation when gathering the main grid solution onto the refined patch boundary. It was also performed using another method from P. McCorquodale et al (labeled ``MC'' in this paper) based on the algorithm given in \cite{Mccorquodalejcp2004}, which employs a more elaborate procedure involving two-ways interpolations between the main grid and the refined patch. A reference case was also run using a single $128\times128$ grid with no refined patch, in which it is observed that the particle propagates toward the closest boundary at an accelerated pace, is reflected specularly at the boundary, then slows down until it reaches its initial position at zero velocity. The particle position histories are shown for the various cases in Fig. \ref{fig:ESselfforce}. In all the cases using the refinement patch, the particle was spuriously reflected near the patch boundary and was effectively trapped in the patch. We notice that linear interpolation performs better than quadratic, and that the simple method implemented in WarpX performs better than the other proposed method for this test (see discussion below).

\begin{figure}[htb]
  \centering
  \includegraphics[width=15cm]{ICNSP_2011_Vay_fig3.png}
  \caption{(left) Maps of the magnitude of the spurious self-force $\epsilon$ in arbitrary units within one quarter of the refined patch, defined as $\epsilon=\sqrt{(E_x-E_x^{ref})^2+(E_y-E_y^{ref})^2}$, where $E_x$ and $E_y$ are the electric field components within the patch experienced by one particle at a given location and $E_x^{ref}$ and $E_y^{ref}$ are the electric field from a reference solution. The map is given for the WarpX and the MC mesh refinement algorithms and for linear and quadratic interpolation at the patch refinement boundary. (right) Lineouts of the maximum (taken over neighboring cells) of the spurious self-force. Close to the interface boundary (x=0), the spurious self-force decreases at a rate close to one order of magnitude per cell (red line), then at about one order of magnitude per six cells (green line).}
  \label{fig:ESselfforcemap}
\end{figure}
The magnitude of the spurious self-force as a function of the macroparticle position was mapped and is shown in Fig. \ref{fig:ESselfforcemap} for the WarpX and MC algorithms using linear or quadratic interpolations between grid levels. It is observed that the magnitude of the spurious self-force decreases rapidly with the distance between the particle and the refined patch boundary, at a rate approaching one order of magnitude per cell for the four cells closest to the boundary and about one order of magnitude per six cells beyond. The method implemented in WarpX offers a weaker spurious force on average and especially at the cells that are the closest to the coarse-fine interface where it is the largest and thus matters most.
We notice that the magnitude of the spurious self-force depends strongly on the distance to the edge of the patch and to the nodes of the underlying coarse grid, but weakly on the order of deposition and size of the patch.

A method was devised and implemented in WarpX for reducing the magnitude of spurious self-forces near the coarse-fine boundaries as follows. Noting that the coarse grid solution is unaffected by the presence of the patch and is thus free of self-force, extra ``transition'' cells  are added around the ``effective'' refined area.
Within the effective area, the particles gather the potential in the fine grid. In the extra transition cells surrounding the refinement patch, the force is gathered directly from the coarse grid (an option, which has not yet been implemented, would be to interpolate between the coarse and fine grid field solutions within the transition zone so as to provide continuity of the force experienced by the particles at the interface). The number of cells allocated in the transition zones is controllable by the user in WarpX, giving the opportunity to check whether the spurious self-force is affecting the calculation by repeating it using different thicknesses of the transition zones. The control of the spurious force using the transition zone is illustrated in Fig.~\ref{fig:ESselfforce}, where the calculation with WarpX using linear interpolation at the patch interface was repeated using either two or four cells transition regions (measured in refined patch cell units). Using two extra cells allowed for the particle to be free of spurious trapping within the refined area and follow a trajectory that is close to the reference one, and using four extra cells improved further to the point where the resulting trajectory becomes undistinguishable from the reference one.
We note that an alternative method was devised for reducing the magnitude of self-force near the coarse-fine boundaries for the MC method, by using a special deposition procedure near the interface \cite{Colellajcp2010}.

%\begin{figure}[htb]
%  \centering
%  \includegraphics[width=15cm]{ICNSP_2011_Vay_fig4.png}
%  \caption{Snapshot from a 3D self-consistent simulation of the injector in the High Current Experiment shows the beam emerging from the source at low energy (blue) and being accelerated (green-yellow-orange) and transported in a four quadrupole front end. The automatic layout of the mesh refinement patches from a 2D axisymmetric simulation of the source area shows 2 levels of refinement, concentrating the finer meshes around the emitter (white curve surface) and the beam edge (dark blue).}
%  \label{fig:ESHCX}
%\end{figure}
%Automatic remeshing has been implemented in WarpX following the procedure described in \cite{Vaynim2005}, refining on criteria based on measures of local charge density magnitude and gradients. AMR WarpX simulations were applied to the modeling of the front end injector of the High Current Experiment (HCX) \cite{Prostprstab2005}, and provided the first numerically converged estimates of phase space beam distorsions, which directly affects beam quality \cite{Vaypop04}. Fig.~\ref{fig:ESHCX} shows snapshots from 2D axisymmetric simulation of the souce area illustrating the automatic placement of refined patches, and 3D simulation of the full injector showing the beam generation, acceleration and transport.

\subsection{Electromagnetic}
The method that is used for electrostatic mesh refinement is not directly applicable to electromagnetic calculations. As was shown in section 3.4 of \cite{Vayjcp01}, refinement schemes relying solely on interpolation between coarse and fine patches lead to the reflection with amplification of the short wavelength modes that fall below the cutoff of the Nyquist frequency of the coarse grid. Unless these modes are damped heavily or prevented from occurring at their source, they may affect particle motion and their effect can escalate if trapped within a patch, via multiple successive reflections with amplification.

To circumvent this issue, an additional coarse patch (with the same resolution as the parent grid) is added, as shown in Fig.~\ref{fig:ESAMR}-right and described in \cite{Vaycpc04}. Both the fine and the coarse grid patches are terminated by Perfectly Matched Layers, reducing wave reflection by orders of magnitude, controllable by the user \cite{Berengerjcp96,Vayjcp02}. The source current resulting from the motion of charged macroparticles within the refined region is accumulated on the fine patch and is then interpolated onto the coarse patch and added onto the parent grid. The process is repeated recursively from the finest level down to the coarsest. The Maxwell equations are then solved for one time interval on the entire set of grids, by default for one time step using the time step of the finest grid. The field on the coarse and fine patches only contain the contributions from the particles that have evolved within the refined area but not from the current sources outside the area. The total contribution of the field from sources within and outside the refined area is obtained by adding the field from the refined grid $F(r)$, and adding an interpolation $I$ of the difference between the relevant subset $s$ of the field in the parent grid $F(s)$ and the field of the coarse grid  $F( c )$, on an auxiliary grid $a$, i.e. $F(a)=F(r)+I[F(s)-F( c )]$. The field on the parent grid subset $F(s)$ contains contributions from sources from both within and outside of the refined area. Thus, in effect, there is substitution of the coarse field resulting from sources within the patch area by its fine resolution counterpart. The operation is carried out recursively starting at the coarsest level up to the finest.
An option has been implemented in which various grid levels are pushed with different time steps, given as a fixed fraction of the individual grid Courant conditions (assuming same cell aspect ratio for all grids and refinement by integer factors). In this case, the fields from the coarse levels, which are advanced less often, are interpolated in time.

The substitution method has two potential drawbacks due to the inexact cancellation between the coarse and fine patches of : (i) the remnants of ghost fixed charges created by the particles entering and leaving the patches (this effect is due to the use of the electromagnetic solver and is different from the spurious self-force that was described for the electrostatic case); (ii) if using a Maxwell solver with a low-order stencil, the electromagnetic waves traveling on each patch at slightly different velocity due to numerical dispersion.
The first issue results in an effective spurious multipole field whose magnitude decreases very rapidly with the distance to the patch boundary, similarly to the spurious self-force in the electrostatic case. Hence, adding a few extra transition cells surrounding the patches mitigates this effect very effectively.
%[Add hyperbolic correction?]
The tunability of WarpX's electromagnetic finite-difference and pseudo-spectral solvers provides the means to optimize the numerical dispersion so as to minimize the second effect for a given application, which has been demonstrated on the laser-plasma interaction test case presented in \cite{Vaycpc04}.
Both effects and their mitigation are described in more detail in \cite{Vaycpc04}.

Caustics are supported anywhere on the grid with an accuracy that is set by the local resolution, and will be adequately resolved if the grid resolution supports the necessary  modes from their sources to the points of wavefront crossing. The mesh refinement method that is implemented in WarpX has the potential to provide higher efficiency than the standard use of fixed gridding, by offering a path toward adaptive gridding following wavefronts.

%\begin{figure}[htb]
%  \centering
%  \includegraphics[width=13cm]{ICNSP_2011_Vay_fig5.png}
%  \caption{Electron density $n_e$ (normalized to the density of the injected plasma) from WarpX simulations  in 2-1/2D for a), b), c) and 3D for d) of a rigid beam (thin light-blue outline) propagating through a neutral plasma, for grid sizes of a) $128\times320$, b) $512\times1280$, c) $128\times320$ (main grid, red box) + $128\times640$ (patch 1, orange box) + $128\times1280$ (patch 2, yellow box), such that the resolution of patch 2 matched the resolution of the grid used for b), d) grid size of $64\times64\times160$ (main grid, red box) + $64\times64\times320$ (patch 1, orange box) + $64\times64\times640$ (patch 2, yellow box). For c) and d),  the number and weight of injected plasma macroparticles was adjusted to keep the number of macroparticles per cell constant in each grid at injection in front of the beam.}
%  \label{fig:EMplasma}
%\end{figure}
%As a test to the electromagnetic PIC implementation, WarpX simulations of wave excitations by a beam propagating through plasma, as described in \cite{Kaganovichpop2004}, were conducted. In these simulations, a hard-edged, elliptical, rigid beam propagates at constant velocity $v_z = 0.5c$ where $c$ is the speed of light through an initially cold neutral plasma of initial density $n_0$. The beam has a flat-top density profile of $n_b = n_0/2$, and an elliptical shape of length $l = 15 c/\omega_p$ and diameter $d = l/10$, where $\omega_p$ is the electron plasma frequency. It is shown in  \cite{Kaganovichpop2004} that waves with a wavenumber of approximately $2\omega_p/v_z$ are generated in the plasma by the beam's electrostatic field, and have larger amplitude inside the beam, due to their interaction with the beam's sharp edges.

%Resolving the beam edge and the small structures developing in the wake inside the beam forces small cell sizes. The resolution that is needed for macroscopic convergence was explored in 2-1/2D in a series of four runs where the number of grid cells was varied from $64\times160$ to $512\times1280$ by incremental factors of 2. Third order spline interpolation was used for the beam and plasma macroparticle current deposition and force gathering. The details of the plasma wake were very similar between the two highest resolution cases, indicating that macroscopic convergence was reached. The results from the runs using $128\times320$ and $512\times1280$ grids are shown in Fig.~\ref{fig:EMplasma}. The result from the highest resolution run serves as the reference for subsequent calculations with mesh refinement.

%A run was conducted where the main grid had $128\times320$ cells and was complemented by two refinement patches (with successive refinement factors of 2 in each direction), such that the resolution in the central patch matched the resolution of the case of reference.
%The number and weight of the injected plasma macroparticles was varied, such that the number of macroparticles per cell in each grid at injection was constant. Results are plotted in Fig.~\ref{fig:EMplasma} (bottom-left) showing a good reproduction of the fine scale structures within the central fine patch in good agreement with the reference case.
%Lastly, a three-dimensional simulation with mesh refinement of the same physical setup was conducted. The grid setup and 3D isosurfaces of the plasma electron density as the beam enters the plasma are shown in Fig.~\ref{fig:EMplasma} (bottom-right). As expected, structures similar to the ones observed in 2D are present within the beam envelope. The speedup achieved by the use of mesh refinement was estimated to be approximately one order of magnitude in 3D.


\documentclass[11pt]{article}
\newcommand\tab[1][1cm]{\hspace*{#1}}
\usepackage{graphicx}
\graphicspath{ {C:/Users/yedkk/Desktop/CS465/hw4} }
\begin{document}
\section{Homework 10}
Name: Kangdong Yuan

\subsection{problem1}
a).I did not work in a group.
\\b).I did not consult without anyone my group members
\\c).I did not consult any non-class materials.

\subsection{problem2}
Create an array B of length n and put 0 in each entry. For each element a $\in$ A , add 1 to B[a.deadline]. For each element in B, if B[a.deadline] $>$ a.deadline, return False (set is not independent). Otherwise, we continue the for loop. If there is no B[a.deadline] $>$ a.deadline in whole for loop return True (set is independent). The time complexity of this algorithm is $O(|A|)$.

\subsection{problem3}
Let OPT(j) be the maximum number of missiles that can be destroyed for the interval $[x_1,x_2,.....x_j]$ . If the input ends at $x_j$ , , so the choice is just when to last activate it before step j. Thus OPT(j) is the best of these
choices over all i.\\
\\
$OPT(j)=max_{o\leq i \leq j} \ [OPT(i)+min\{x_j, f(j-i)\}]$ \\
\\
set OPT(0) = 0 \\
for j = 1 to n \\
\tab $OPT(j)=max_{o\leq i \leq j} \ [OPT(i)+min\{x_j, f(j-i)\}]$\\
endfor\\
return OPT(n)\\
The running time is O(n) per iteration, for a total of $O(n^2)$.\\
\\
\subsection{problem4}
a).\\
This greedy approach will not be optimal, it will not give us best solution.\\
For example sequence (2,20,2,2,1,1). If the first player use  greedy approach and takes the first card with a value of 2 then the second player can take the card witha value of 20 and win. \\
The better solution the first player is to take the last card with a value of 1. Then the second player will take either the 2 or the remaining 1 and the first player can take 20.\\
\\
b).\\
we define that OPT(i,j) be the difference between, i is the largest total score first player can obtain, j is corresponding score of the second player, on the sequence interval $s_i \ to \ s_j$. And $V[i]$ is the value of each card, n is number of card in original sequence.\\
\\
The Pre-computation code is \\
Pseudo-code\\
set the inital value\\
for i = 1...n:\\
\tab OPT[i, i] = v[i]\\
\\
for j from i to n:\\
\tab for i from j to 1:\\
\tab \tab OPT[i, j] = max (v[i] - OPT(i+1,j), v[j] - OPT(i,j-1))\\
return OPT array\\
\\
The look up process:\\
choose $s_i$ (first in squence), if $OPT[i,j]=v[i]-OPT(i+1,j)$\\
choose $s_j$ (last in squence), otherwise\\
\\
The time complexity for Pre-computation is $O(n^2)$, the time complexity for each lookup is $O(1)$.

\end{document}


\section{Evaluation}\label{sec:evaluation}

% The source counts were generated by:
% $ cd benchmarks/haskell16/pos/
% $ find . -type f -name '*.hs' -exec sed -i '' s/\{-@/\{-#LH/ {} +
% $ sloccount

\begin{table}[t!]
\captionsetup{justification=centering}
\caption{Summary of Refinement Reflection Case Studies.}
\label{fig:eval-summary}
\begin{center}
\begin{tabular}{lllr}
\toprule
  \multicolumn{3}{l}{\textbf{CATEGORY}}              & \textbf{LOC} \\
\toprule
  \textbf{I.} & \multicolumn{3}{l}{\textbf{Arithmetic}} \\[0.05in]
   & Fibonacci      & \S~\ref{sec:refinementreflection:overview}          &  48 \\ % Overview.hs
   & Ackermann      & \citep{ackermann}
                    , Fig.~\ref{fig:ackermann}       & 280 \\ % Ackermann.hs

  \midrule

  \textbf{II.} & \multicolumn{3}{l}{\textbf{Algebraic Data Types}} \\[0.05in]

  & Fold Universal & \citep{agdaequational}          & 105 \\ % FoldrUniversal.hs
  & Fold Fusion    & \citep{agdaequational}          &     \\

  \midrule

  \textbf{III.} & \textbf{Typeclasses} & Table~\ref{fig:laws} & \\[0.05in]
  & Monoid         & \tPeano, \tMaybe, \tList        & 189 \\ % Monoid*.hs
  & Functor        & \tMaybe, \tList, \tId, \tReader & 296 \\ % Functor*.hs - FunctorReader.hs
  & Applicative    & \tMaybe, \tList, \tId, \tReader & 578 \\ % Applicative*.hs
  & Monad          & \tMaybe, \tList, \tId, \tReader & 435 \\ % Monad*.hs

  \midrule

  \textbf{IV.} & \multicolumn{3}{l}{\textbf{Functional Correctness}} \\[0.05in]
  & SAT Solver     & \citep{Zombie}                  & 133 \\ % Solver.hs
  & Unification    & \citep{Sjoberg2015}             & 200 \\ % Unification

  \midrule

  \textbf{V.} & \multicolumn{3}{l}{\textbf{Deterministic Parallelism}} \\[0.05in]
  & Concurrent Sets     & \S~\ref{sec:set}           & 906 \\ % VerifiedEq/Ord + PureSet.hs + SLSet.hs
  & $n$-body simulation & \S~\ref{sec:nbody}         & 930 \\ % VerifiedEq/Ord + Inj/Iso + allpairs.hs
  & Parallel Reducers   & \S~\ref{sec:reducer}       &  55 \\ % VerifiedSemigroup + Iso + IntegerSumReduction2.hs

  \midrule

  \multicolumn{3}{l}{\textbf{TOTAL}}                 & 4155 \\
\bottomrule
\end{tabular}
\end{center}
\end{table}

We have implemented refinement reflection
in \toolname.
%
In this section, we evaluate our approach
by using \toolname to verify a variety of
deep specifications of Haskell functions
drawn from the literature and categorized
in Table~\ref{fig:eval-summary},
totalling about 4000 lines of specifications
and proofs.
%
Next, we detail each of the first four classes of
specifications, illustrate how they were
verified using refinement reflection, and
discuss the strengths and weaknesses of
our approach.
%
\emph{All} of these proofs require refinement
reflection, \ie are beyond the scope of shallow
refinement typing.

\mypara{Proof Strategies.}
%
Our proofs use three building blocks, that are seamlessly
connected via refinement typing:
%
\begin{itemize}
  \item \emphbf{Un/folding}
     definitions of a function @f@ at
     arguments @e1...en@, which due
     to refinement reflection, happens
     whenever the term @f e1 ... en@
     appears in a proof.
     For exposition, we render the function
     whose un/folding is relevant as @#f#@;

  \item \emphbf{Lemma Application}
     which is carried out by using
     the ``because'' combinator
     ($\because$) to instantiate
     some fact at some inputs;

  \item \emphbf{SMT Reasoning}
     in particular, \emph{arithmetic},
     \emph{ordering} and \emph{congruence closure}
     which kicks in automatically (and predictably!),
     allowing us to simplify proofs by not
     having to specify, \eg which subterms
     to rewrite.
\end{itemize}

\subsection{Arithmetic Properties} \label{subsec:arith} \label{subsec:ackermann}

The first category of theorems pertains to the textbook
Fibonacci and Ackermann functions.
%
The former were shown in \S~\ref{sec:refinementreflection:overview}.
%
The latter are summarized in Figure~\ref{fig:ackermann},
which shows two alternative definitions for the
Ackermann function.
%
We proved equivalence of the definition (Prop 1)
and various arithmetic relations between
them (Prop 2 --- 13), by mechanizing the
proofs from~\cite{ackermann}.

\begin{figure}[t!]
\centering
\captionsetup{justification=centering}
\textbf{Ackermann's Function}
\[
\begin{array}{lr}
\ack{n}{x} \defeq
 \left\{
\begin{array}{l}
\setlength\arraycolsep{0pt}
\begin{array}{ll}
      x+2 &\quad \text{, if}\ n=0 \\
      2   &\quad \text{, if}\ x=0 \\
\end{array} \\
\ack{n-1}{\ack{n}{x-1}}
\end{array}
\right.
&
\iack{h}{n}{x} \defeq
 \left\{
\begin{array}{l}
      x \quad \text{, if}\ h=0 \\
      \ack{n}{\iack{h-1}{n}{x}}
\end{array}
\right.
\end{array}
 \]

\textbf{Properties}
$$
\begin{array}{lrcrcl}
1.&                &&            \ack{n+1}{x}   &=& \iack{x}{n}{2}\\
2.&                &&            x + 1          &<& \ack{n}{x}\\
3.&                &&            \ack{n}{x}     &<& \ack{n}{x+1}\\
4.& x < y          &\Rightarrow& \ack{n}{x}     &<& \ack{n}{y}\\
5.& 0 < x          &\Rightarrow& \ack{n}{x}     &<& \ack{n+1}{x}\\
6.& 0 < x, n < m   &\Rightarrow& \ack{n}{x}     &<& \ack{m}{x}\\
7.&                &&            \iack{h}{n}{x} &<& \iack{h+1}{n}{x}\\
8.&                &&            \iack{h}{n}{x} &<& \iack{h}{n}{x+1}\\
9.& x<y            &\Rightarrow& \iack{h}{n}{x} &<& \iack{h}{n}{y}\\
10.&               &\Rightarrow& \iack{h}{n}{x} &<& \iack{h}{n+1}{x}\\
11.& 0<n, l-2 < x  &\Rightarrow& x + l          &<& \ack{n}{x}\\
12.& 0<n, l-2 < x  &\Rightarrow& \iack{l}{n}{x} &<& \ack{n+1}{x}\\
13.&               &&            \iack{x}{n}{y} &<& \ack{n+1}{x+y}\\
\end{array}
$$
\caption[Ackermann Properties verified using \toolname.]{Ackermann Properties~\citep{ackermann},
$\forall n, m, x, y, h, l \geq 0$}
\label{fig:ackermann}
\end{figure}

\mypara{Monotonicity}
%
Prop 3. shows that \ack{n}{x} is increasing on $x$.
%
We derived Prop 4. by applying @fMono@ theorem
from \S~\ref{sec:examples} with input function
the partially applied Ackermann Function
$\ack{n}{\star}$.
%
Similarly, we derived the monotonicity Prop 9. by
applying @fMono@ to the locally increasing Prop. 8
and $\iack{h}{n}{\star}$.
%
Prop 5. proves that \ack{n}{x} is increasing
on the \emph{first} argument $n$.
%
As @fMono@ applies to the \emph{last} argument
of a function, we cannot directly use it to
derive Prop 6.
%
Instead, we define a variant @fMono2@ that works
on the first argument of a binary function, and
use it to derive Prop 6.

%%\mypara{Existentials}
%%%
%%Properties 11. and 12. are described in~\citep{ackermann}
%%to hold for almost every $x$.
%%%
%%That is, Property 11. is described as
%%$\exists x_0. x_0 < x \Rightarrow x + l < \ack{n}{x}$.
%%%
%%Refinement types cannot express existentials,
%%thus expressing the above property is (currently)
%%not feasible, but the minimum $x$ was easy to retrieve.
%%%
%%Thus, we expressed the above statement by specifying $x_0 = l - 2$.
%%%
%%\NV{``Almost'' means in English for large x.
%%In math it translates to there exist some x0 such that...
%%in LiquidHaskell, and due to lack of existentials
%%I had to find (``retrieve'') an x0 = l-2 above which
%%the property holds For almost see big o notation, where
%%there exists a c such that...to specify these properties
%%in LH you need to give a concrete c But, this paragraph
%%summarizes a lot of internal thinking, so feel free to
%%rephrase. I wanted it in, because when I saw the lemma
%%stating this property holds almost everywhere I though
%%we could not express it, but we can!}

%
\mypara{Constructive Proofs}
%
In \citep{ackermann} Prop 12. was proved by constructing
an auxiliary \emph{ladder} that counts the number of
(recursive) invocations of the Ackermann function, and
uses this count to bound \iack{h}{n}{x} and \ack{n}{x}.
%
It turned out to be straightforward and natural
to formalize the proof just by defining the
@ladder@ function in Haskell, reflecting it,
and using it to formalize the algebra from~\citep{ackermann}.

\subsection{Algebraic Data Properties}
\label{subsec:fold}

The second category of properties pertain to
algebraic data types.
%, \eg \emph{folding} over lists.

\mypara{Fold Univerality}
%
Next, we proved properties of list folding, such as
the following, describing the \emph{universal}
property of right-folds~\citep{agdaequational}:
%
\begin{code}
foldr_univ
  :: f:(a -> b -> b)
  -> h:([a] -> b)
  -> e:b
  -> ys:[a]
  -> base:{h [] = e }
  -> stp:(x:a ->l:[a]->{h(x:l) = f x (h l)})
  -> {h ys = foldr f e ys}
\end{code}
%
Our proof @foldr_univ@ differs from the one in Agda,
in two ways.
%
First, we encode Agda's universal quantification over
@x@ and @l@ in the assumption @stp@ using a function type.
%
Second, unlike Agda, \toolname
does not support implicit arguments,
so at \emph{uses} of @foldr_univ@
the programmer must explicitly
provide arguments for @base@
and @stp@, as illustrated below.

\mypara{Fold Fusion}
%
Let us define the usual composition operator:
%
\begin{code}
  reflect . :: (b -> c) -> (a -> b) -> a -> c
  f . g     = \x -> f (g x)
\end{code}
%
We can prove the following @foldr_fusion@ theorem
(that shows operations can be pushed inside a @foldr@),
by applying @foldr_univ@ to explicit @bas@ and @stp@ proofs:
%
\begin{code}
  foldr_fusion
   :: h:(b -> c)
   -> f:(a -> b -> b)
   -> g:(a -> c -> c)
   -> e:b -> z:[a] -> x:a -> y:b
   -> fuse: {h (f x y) = g x (h y)})
   -> {(h . foldr f e) z = foldr g (h e) z}

  foldr_fusion h f g e ys fuse
    = foldr_univ g (h . foldr f e) (h e) ys
        (fuse_base h f e)
        (fuse_step h f e g fuse)
\end{code}
%
where @fuse_base@ and @fuse_step@ prove the
base and inductive cases. For example
the type of @fuse_base@ is the following theorem
%
\begin{code}
  fuse_base :: h:(b->c) -> f:(a->b->b) -> e:b
            -> {(h . foldr f e) [] = h e}
\end{code}

\subsection{Typeclass Laws}\label{subsec:list}

\begin{table}[t!]
\captionsetup{justification=centering}
\caption{Typeclass Laws verified using \toolname.}
\label{fig:laws}
\begin{center}
\begin{tabular}{rl}

\toprule

\multicolumn{2}{c}{\textbf{Monoid}} \\
{Left Ident.}  & $\emempty\ x\ \emappend\  \equiv x$  \\
{Right Ident.} & $x\ \emappend\ \emempty \equiv x$  \\
{Associativity}  & $(x\ \emappend\ y)\ \emappend\ z \equiv x\ \emappend\ (y\ \emappend\ z)$ \\

\midrule

\multicolumn{2}{c}{\textbf{Functor}} \\
{Ident.}     & $\efmap\ \eid\ xs \equiv \eid\ xs$ \\
{Distribution} & $\efmap\ (g\ecompose\ h)\ xs \equiv (\efmap\ g\ \ecompose\ \efmap\ h)\ xs$\\

\midrule

\multicolumn{2}{c}{\textbf{Applicative}} \\

{Ident.}      & $\epure \eid \eseq\ v \equiv v$ \\
{Compos.}     & $\epure (\ecompose) \eseq u \eseq v \eseq w \equiv u \eseq (v \eseq w)$ \\
{Homomorph.}  & $\epure\ f\ \eseq\ \epure\ x \equiv \epure\ (f\ x)$\\
{Interchange} & $u\ \eseq\ \epure\ y \equiv \epure\ (\$\ y) \ \eseq \ u$ \\

\midrule
\multicolumn{2}{c}{\textbf{Monad}} \\
{Left Ident.}   & $\ereturn\ a \ebind f \equiv f\ a$ \\
{Right Ident.}  & $m \ebind \ereturn \equiv m$ \\
{Associativity} & $(m\ebind f) \ebind g \equiv m\ebind (\lambda x \rightarrow f\ x \ebind g)$\\
\bottomrule
\end{tabular}
\end{center}
\end{table}
We used \toolname to prove the Monoid, Functor,
Applicative and Monad Laws, summarized in
Table~\ref{fig:laws}, for various user-defined
instances summarized in Table~\ref{fig:eval-summary}.

%% The purpose of these proofs is to investigate the
%% proving abilities of \libname.
%% For this purpose, we defined the appropriate class
%% operators on user defined lists, instead of using
%% Haskell's predefined class instances.
%% %
%% In the near future, we plan to embed these proofs
%% to check the laws on real Haskell instances,
%% but this requires some engineering from the
%% \liquidHaskell team.

\mypara{Monoid Laws}
%
A Monoid is a datatype equipped with an associative
binary operator $\emappend$ and an \emph{identity}
element $\emempty$.
%
We use \toolname to prove that
%
@Peano@ (with @add@ and @Z@),
@Maybe@ (with a suitable @mappend@ and @Nothing@), and
@List@ (with append @++@ and @[]@) satisfy the monoid laws.
%
For example, we prove that @++@ (\S~\ref{subsec:list})
is associative by reifying the textbook proof~\cite{HuttonBook}
into a Haskell function, where the induction
corresponds to case-splitting and recurring
on the first argument:
%
\begin{mcode}
  assoc :: xs:[a] -> ys:[a] -> zs:[a] -> {(xs ++ ys) ++ zs = xs ++ (ys ++ zs)}

  assoc [] ys zs     = ([] #++# ys) ++ zs
                     =. [] #++# (ys ++ zs)
                     ** QED
  assoc (x:xs) ys zs = ((x:  xs)#++# ys) ++ zs
                     =. (x: (xs ++ ys))#++# zs
                     =.  x:((xs ++ ys) ++ zs)
                     =.  x: (xs ++ (ys ++ zs))
                         $\because$ assoc xs ys zs
                     =. (x:xs)  #++# (ys ++ zs)
                     ** QED
\end{mcode}

\mypara{Functor Laws}
%
A type is a functor if it has a function
@fmap@ that satisfies the \emph{identity}
and \emph{distribution} (or fusion) laws
in Table~\ref{fig:laws}.
%
For example, consider the proof of
the @fmap@ distribution law for the lists,
also known as ``map-fusion'', which is the
basis for important optimizations in
GHC~\cite{ghc-map-fusion}.
%
We reflect the definition of @fmap@:
%
\begin{code}
  reflect map :: (a -> b) -> [a] -> [b]
  map f []     = []
  map f (x:xs) = f x : fmap f xs
\end{code}
%
and then specify fusion and verify it by an inductive proof:
% by induction (recursion) on the list argument:
%
\begin{mcode}
  map_fusion :: f:(b -> c) -> g:(a -> b) -> xs:[a]
             -> {map (f . g) xs = (map f . map g) xs}
\end{mcode}

%%\begin{mcode}
%%  map_fusion f g []
%%    =  ((map f) #.# (map g)) []
%%    =. (map f) (#map# g [])
%%    =. #map# f []
%%    =. []
%%    =. #map# (f . g) []
%%    ** QED
%%
%%  map_fusion f g (x:xs)
%%    =   #map# (f . g) (x:xs)
%%    =. (f . g) x : map (f . g) xs
%%    =. (f . g) x : (map f #.# map g) xs
%%       $\because$  map_fusion f g xs
%%    =. (f# . #g) x : map f (map g xs)
%%    =. f   (g  x): map f (map g xs)
%%    =. #map# f (g x: map g xs)
%%    =. map f   (#map# g (x:xs))
%%    =. (map f #.# map g)(x:xs)
%%    ** QED
%%\end{mcode}
%%
% \NV{Say why we need defunctionalization}
% \NV{We use app function like HALO (link to the theory)}

% \mypara{Applicative}

\mypara{Monad Laws}
%
The monad laws, which relate the
properties of the two operators
$\ebind$ and $\ereturn$ (Table~\ref{fig:laws}),
refer to $\lambda$-functions,
thus their proof exercises
our support for defunctionalization
and $\eta$- and $\beta$-equivalence.
% and the extensionality axioms to prove.
%
For example, consider the proof of the
associativity law for the list monad.
First, we reflect the bind operator:
%
\begin{code}
  reflect (>>=) :: [a] -> (a -> [b]) -> [b]
  (x:xs) >>= f = f x ++ (xs >>= f)
  []     >>= f = []
\end{code}
%
Next, we define an abbreviation for the associativity property:
%
\begin{code}
  type AssocLaw m f g = {m >>= f >>= g = m >>= (\x -> f x >>= g)}
\end{code}
%
Finally, we can prove that the list-bind is associative:
%
\begin{mcode}
  assoc :: m:[a] -> f:(a ->[b]) -> g:(b ->[c]) -> AssocLaw m f g
  assoc [] f g
    =  [] #>>=# f >>= g
    =. [] #>>=# g
    =. []
    =. [] #>>=# (\x -> f x >>= g) ** QED

  assoc (x:xs) f g
    =  (x:xs) #>>=# f  >>= g
    =. (f x ++ xs >>= f) >>= g
    =. (f x >>= g) ++ (xs >>= f >>= g)
       $\because$ bind_append (f x) (xs >>= f) g
    =. (f x >>= g) ++ (xs >>= \y -> f y >>= g)
       $\because$ assoc xs f g
    =. (\y -> f y >>= g) x ++ (xs >>= \y -> f y >>= g)
       $\because$ $\beta$eq f g x
    =. (x:xs) #>>=# (\y -> f y >>= g) ** QED
\end{mcode}
%
Where the bind-append fusion lemma states that:
%
\begin{code}
  bind_append :: xs:[a] -> ys:[a] -> f:(a -> [b])
              -> {(xs++ys) >>= f = (xs >>= f)++(ys >>= f)}
\end{code}
%
Notice that the last step requires
$\beta$-equivalence on anonymous
functions, which we get by explicitly
inserting the redex in the logic,
via the following lemma with @trivial@ proof
%
\begin{mcode}
  $\beta$eq :: f:_ -> g:_ -> x:_ -> {bind (f x) g = (\y -> bind (f y) g) x}
  $\beta$eq _ _ _ = trivial
\end{mcode}
%
% \RJ{TODO:discuss $\alpha$ and $\beta$ equality, axiom text commented out}

%%\NV{This is new, text can be simplified}
%%\mypara{The Reader Monad} was the most challenging of our benchmarks,
%%as the @Reader r a@ data type wraps the value @a@ inside a reader-only state,
%%represented by a lambda argument @r@
%%%
%%\begin{mcode}
%%  data Reader r a = R { runR :: r -> a }
%%\end{mcode}
%%%
%%Because of the functional structure of the Reader data type,
%%equational proofs proceed via unfolding wrapped inside the abstracted
%%state, thus proving equalities made heavy use of the extensionality
%%function equality~\ref{subsec:extensionality} requiring
%%usage $\eta$-reduced proof arguments.
%%%
%%As an example, proof of monadic associativity performs an
%%unfolding if the reflected bind wrapped inside \textit{two} lambda arguments:
%%%
%%\begin{code}
%%     R (\r2 -> runR ((\r4 ->
%%      R (\r3 ->
%%       runR (g ((runR (f r4)) r3)) r3)
%%     ) (x r2)) r2)
%%  =. R (\r2 -> runR ((\r4 ->
%%      f r4 #>>=# g
%%     ) (x r2)) r2)
%%\end{code}
%%%
%%Even though the intermediate equation step seemed
%%straightforward, it required usage of extensionality equality twice,
%%thus two intermediate $\eta$-expanded helper proofs
%%
%%% To prove this equality, in the logic,
%%% the anonymous functions are represented
%%% as functional variables axiomatized with
%%% extensionality axioms.
%%% %
%%% Thus, in the logic, we define @f'@ and
%%% the axioms @forall x. f' x = f x >>= g@
%%% and @forall g x. (f' x = g x) => f' = g@.
%%% %
%%% These two axioms are sufficient to prove
%%% 1. $\eta$-equivalence that is required in
   %%% the last step of the inductive case; and
%%% 2. $\beta$-equivalence that is required
   %%% to prove that our proof
   %%% @xs >>= f >>= g =. xs >>= (\y -> f y >>= g)@
   %%% implies the specification.

%% In all, most of the proofs are straightforward,
%% using inductive reasoning in the structure of
%% the data constructors and rewriting the definitions
%% of axiomatized functions.

\subsection{Functional Correctness} \label{subsec:programs}

Finally, we proved correctness of two programs
from the literature: a SAT solver and a Unification
algorithm.

\mypara{SAT Solver}
%
We implemented and verified the simple
SAT solver used to illustrate and evaluate
the features of the dependently typed language
Zombie~\citep{Zombie}.
%
The solver takes as input a formula @f@
and returns an assignment that
\emph{satisfies} @f@ if one exists.
%
\begin{code}
  solve :: f:Formula -> Maybe {a:Asgn|sat a f}
  solve f = find (`sat` f) (assignments f)
\end{code}
%
Function @assignments f@ returns all possible
assignments of the formula @f@ and @sat a f@
returns @True@ iff the assignment @a@ satisfies
the formula @f@:
%
\begin{code}
  reflect sat :: Asgn -> Formula -> Bool
  assignments :: Formula -> [Asgn]
\end{code}
%
Verification of @solve@ follows simply by
reflecting @sat@ into the refinement logic,
and using (bounded) refinements to show
that @find@ only returns values on which
its input predicate yields @True@ from chapter~\ref{boundedrefinements}.
%
\begin{code}
  find :: p:(a -> Bool) -> [a] -> Maybe {v:a | p v}
\end{code}

\mypara{Unification}
%
As another example, we verified the
unification of first order terms, as
presented in~\citep{Sjoberg2015}.
%
First, we define a predicate alias for
when two terms @s@ and @t@ are equal
under a substitution @su@:
%
\begin{code}
  eq_sub su s t = apply su s == apply su t
\end{code}
%
Now, we can define a Haskell function
@unify s t@ that can diverge, or return
@Nothing@, or return a substitution @su@
that makes the terms equal:
%
\begin{code}
  unify :: s:Term -> t:Term -> Maybe {su| eq_sub su s t}
\end{code}
%
For the specification and verification
we only needed to reflect @apply@ and
not @unify@; thus we only had to verify
that the former terminates, and not the latter.
%
% not that @unify@ terminates, which is a
% complicate proof.

%%% HERE
%
As before, we prove correctness by invoking
separate helper lemmas.
%
For example to prove the post-condition
when unifying a variable @TVar i@ with
a term @t@ in which @i@ \emph{does not}
appear, we apply a lemma @not_in@:
%
\begin{mcode}
  unify (TVar i) t2
    | not (i Set_mem freeVars t2)
    = Just (const [(i, t2)] $\because$ not_in i t2)

\end{mcode}
%%
\ie if @i@ is not free in @t@,
the singleton substitution yields @t@:
%
\begin{code}
  not_in :: i:Int
         -> t:{Term | not (i Set_mem freeVars t)}
         -> {eq_sub [(i, t)] (TVar i) t}
\end{code}
%%
%% \NV{Emphasize how real world - diverging code co-exists with refinement reflection}


\chapter{Model architectures}
\label{app:model_training}

This chapter goes into more detail on the specific architectures for the models presented in \cref{chap:method}. Specifically, the output shape, number of parameters and the connections for each layer in all models is presented in the form of Tables \ref{tab:Models_Baseline}, \ref{tab:Models_GCN}, \ref{tab:Models_Poptoy} and \ref{tab:Models_Popencoder}. When numbers are presented for either output shape or number of parameters they refer to age/sex.

\todo{Lägg in modellnamn i tabellen}
\begin{table}[H]
    \centering
    \caption{Baseline}
    \begin{tabular}{c|c c c}
         Layer & Output shape & Params & Connected to\\ \hline\hline
         Input layer A &(210) & & \\ \hline
         Dense layer & (1/2) & 211/422 & Input layer A \\ \hline\hline
         Total params & & 211/422
    \end{tabular}
    \label{tab:Models_Baseline}
\end{table}

\begin{table}[H]
    \centering
    \caption{GCN}
    \begin{tabular}{c|c c c}
         Layer & Output shape & Params & Connected to\\ \hline\hline
         Input layer popgraph &(42, 42) & & \\ \hline
         Input layer X &  (42, 42)& & \\ \hline
         GCN layer 1 & (42,10) & 430 & \thead{Input layer popgraph \\ Input layer X}   \\ \hline
         GCN layer 2 & (42,10)& 110 & GCN layer 1\\ \hline
         GCN layer 3 & (42,10)& 110  &GCN layer 2\\ \hline
         Concatenate &(42, 30)  & 0 & \thead{GCN layer 1\\GCN layer 2\\GCN layer 3} \\ \hline
         Dense layer & (1/2) & 1261/2522 & Concatenate \\ \hline\hline
         Total params & & 1911/3172
    \end{tabular}
    \label{tab:Models_GCN}
\end{table}

\begin{table}[H]
    \centering
    \caption{Poptoy}
    \begin{tabular}{c|c c c}
         Layer & Output shape & Params & Connected to\\ \hline\hline
         Input layer popgraph &(100, 100) & & \\ \hline
         Input layer X &  (100, 100)& & \\ \hline
         GCN layer 1 & (100,10) & 20 & \thead{Input layer popgraph \\ Input layer X}   \\ \hline
         GCN layer 2 & (100,10)& 110 & GCN layer 1\\ \hline
         GCN layer 3 & (100,10)& 110  &GCN layer 2\\ \hline
         GCN layer 4 & (100,10)& 110  &GCN layer 3\\ \hline
         GCN layer 5 & (100,10)& 110  &GCN layer 4\\ \hline
         Concatenate & (100, 50)  & 0 & \thead{GCN layer 1\\GCN layer 2\\GCN layer 3\\GCN layer 4\\GCN layer 5} \\ \hline
         Dense layer 1& (100, 32) & 1632 & Concatenate \\
         Dense layer 2& (100, 16) & 528 & Dense layer 1\\
         Dense layer 3& (100, 1/2) & 17/34 & Dense layer 2\\
         \hline\hline
         Total params & & 3627/3644
    \end{tabular}
    \label{tab:Models_Poptoy}
\end{table}

\begin{table}[H]
    \centering
    \caption{Popencoder }
    \begin{tabular}{c|c c c}
         Layer & Output shape & Params & Connected to\\ \hline\hline
         Input layer A &(100, 42,42) & & \\ \hline
         Input layer X &  (100, 42,42)& & \\ \hline
         Input layer popgraph &  (100,100)& & \\ \hline
         Encoder GCN layer 1 & (100,42,10) & 430 & \thead{Input layer A \\ Input layer X} \\ \hline
         Encoder GCN layer 2 & (100,42,10) & 110 & \thead{Encoder GCN layer 1} \\ \hline
         Concatenate 1& (100, 42, 20)  & 0 & \thead{Encoder GCN layer 1\\Encoder GCN layer 2} \\ \hline
         Dense encoder& (100,1/2) & 841/1682 & \thead{Concatenate 1}   \\ \hline
         GCN layer 1 & (100,10) & 1010 & \thead{Input layer popgraph \\ Dense encoder}   \\ \hline
         GCN layer 2 & (100,10)& 110 & GCN layer 1\\ \hline
         GCN layer 3 & (100,10)& 110  &GCN layer 2\\ \hline
         GCN layer 4 & (100,10)& 110  &GCN layer 3\\ \hline
         GCN layer 5 & (100,10)& 110  &GCN layer 4\\ \hline
         Concatenate 2& (100, 51/52)  & 0 & \thead{GCN layer 1\\GCN layer 2\\GCN layer 3\\GCN layer 4\\GCN layer 5} \\ \hline
         Dense layer 1& (100, 32) & 1664/1696 & Concatenate 2\\
         Dense layer 2& (100, 16) & 528 & Dense layer 1\\
         Dense layer 3& (100, 1/2) & 17/34 & Dense layer 2\\
         \hline\hline
         Total params & & 4050/4950
    \end{tabular}
    \label{tab:Models_Popencoder}
\end{table}
% -- Model parameters
% -- Training details