% !TeX root = ../main.tex
\chapter{Development of Electronic Structure Theory}
Electronic structure usually refers to the quantum state of electrons in electromagnetic field produced by nuclei and the electrons themselves.\cite{elecstruc}
In principle, state of electrons and nuclei must be determined simultaneously by many-body Schrodinger equation.
However, the fact that nuclei are much heavier than electrons make the treatment of nuclei as stationary point charge a good approximation for ground state calculation of most quantum systems, which is the well-known Born-Oppenheimer approximation.\cite{sakurai}
The many-body Hamiltonian of electrons under Born-Oppenheimer approximation is
\begin{equation}
H=\sum_{i=1}^{N}\left(\frac{\boldsymbol{p}_{i}^{2}}{2 m}-\frac{Z e^{2}}{r_{i}}\right)+\sum_{i>j} \frac{e^{2}}{|\boldsymbol{x}_{i}-\boldsymbol{x}_{j}|}
\end{equation}
which contains a one-body part and a two-body part.
The two-body part couples all the electrons and make the exact solution of Schrodinger equation very difficult and almost impossible.
Thus, appropriate approximation are needed.

\section{Hartree-Fock Method}
The most basic and famous approximation among all of them is Hartree-Fock method.\cite{hartree}
Hartree-Fock method approximates the many-body wavefuntion as a single Slater determinant in which each row represents a molecular orbital.
Usually the molecular orbitals are linear combinations of atomic orbitals.
Then the coefficients are chosen to make the energy of the whole system as low as possible, which results in the following nonlinear Hartree-Fock Equation:
\begin{equation}
\mathbf{F} \mathbf{C}=\mathbf{S} \mathbf{C} \epsilon
\end{equation}
where
\begin{equation}
\hat{F}(i)=\hat{h}(i)+\sum_{j=1}^{n / 2}\left[2 \hat{J}_{j}(i)-\hat{K}_{j}(i)\right]
\end{equation}
is Fock matrix,
\begin{equation}
\mathbf{S}_{j k}=\langle b_{j} | b_{k}\rangle=\int \Psi_{j}^{*} \Psi_{k} d \tau
\end{equation}
is Overlap matrix,
$\mathbf{C}$ is decomposition coefficients of molecular orbitals on atomic orbitals,
$\epsilon$ is energies of molecular orbitals.

The fact that $\mathbf{C}$ is implicitly contained in $\mathbf{F}$ make the Hartree-Fock Equation nonlinear and usually solved by Self-Consistent Field (SCF) method.

Essentially, Hartree-Fock is a mean-field theory which appropriate the electron-electron repulsion potential by averaging over the molecular orbitals.
Thus, instantaneous interactions between electrons are neglected, which make the decoupling between electrons possible.
All the effects arisen from deviations from the mean-field approximation are collectively used as a definition of electron correlation.

Under non-relativity and Born-Oppenheimer approximation, electron correlation is always the center topic of electronic structure.
Huge amount of efforts have been put on different methods of treatment of electron correlation,
including various Post-Hartree-Fock methods, Density Functional Theory and other less known methods like reduced density matrix \cite{reduceddm} and density matrix renormalization group. \cite{dmrg}

\section{Post-Hartree-Fock Methods}
Post-Hartree-Fock methods are the set of methods developed to improve on the Hartree-Fock method. They add at least part of electron correlation energy while Hartree-Fock neglects electron correlation completely.
Here electron correlation energy is defined as the energy difference between true ground state and Hartree-Fock ground state. Since Hartree-Fock energy is the upper bound to the exact energy, electron correlation energy is always negative.
Famous Post-Hartree-Fock methods includes Configuration Interaction (CI) \cite{mqc}, Coupled Cluster (CC) \cite{coupledcluster}, M{\o}ller–Plesset (MP) perturbation theory \cite{mp2}, and Algebraic Diagrammatic Construction (ADC).

\subsection{Configuration Interaction}
Among all the approaches to explore electron correlation energy, CI is conceptually the simplest, although not computationally the simplest.
The basic idea is to diagonalize the N-electron Hamiltonian in a basis N-electron function.
If all possible configuration in a particular basis set is used for linear combination, then CI reduces to full CI (FCI).
However, the computational cost of FCI is very large, since there will be $C_{2K}^{N}$ different Slater orbitals, which increases exponentially with the size of the system.
Thus, usually only part of the configurations are used in a CI calculation.

The CI wavefunction is usually written as:
\begin{equation}
\ket{\Psi_0}=t_0 \ket{\Phi_0} + \sum_{ia} t^{a}_{i}\ket{\Phi^{a}_{i}}+\sum_{ijab}t^{ab}_{ij}\ket{\Phi^{ab}_{ij}}+ \dots
\end{equation}
where $\ket{\Phi_0}$ is the Hartree-Fock ground state, and the following terms on right-hand side (RHS) of the equation are defined as single excitations, double excitations, etc.

In a symbolic form, the CI wavefunction can also be written as
\begin{equation} \label{CIexcite}
	\ket{\Psi_0}=t_0\ket{\Phi_0}+t_S\ket{S}+t_D\ket{D}+t_T\ket{T}+t_Q\ket{Q}+\dots
\end{equation}

The following is the matrix structure of CI Hamiltonian.
\begin{equation}
H=
\left[
\begin{array}{cccccc}
	\langle\Phi_{0}|H| \Phi_{0} \rangle & & & & & \dots
	\\
	0 & \langle S|H| S\rangle & & & & \dots
	\\
	\langle D|H| \Phi_{0} \rangle & \langle D|H| S\rangle & \langle D|H| D\rangle & & & \dots
	\\
	0 & \langle T|H| S\rangle & \langle T|H| D\rangle & \langle T|H| T\rangle & & \dots
	\\
	0 & 0 & \langle Q|H| D\rangle & \langle Q|H| T\rangle & \langle Q|H| Q\rangle & \dots
	\\
	{\vdots} & {\vdots} & {\vdots} & {\vdots} & {\vdots} & {\vdots}
\end{array}
\right]
\end{equation}

\subsection{Discussion of Size Consistency}
Size consistency is a concept relating to how the behaviour of quantum chemistry calculations changes with size. \cite{sizeconsistency}
Let A and B be two non-interacting systems.
If a given theory for the evaluation of the energy is size consistent, then the energy of the supersystem A+B, separated by a sufficiently large distance so there is essentially no shared electron density, is equal to the sum of the energy of A plus the energy of B taken by themselves ($E(A+B)=E(A)+E(B)$).
Size consistency is a vital behaviour for any method to calculate some properties like obtaining dissociation curves.

Unfortunately, standard CI is not size consistent, which is one of the main problems of CI.
To better understand the size inconsistency of CI, we can think about CI single (CIS) method, in which only single excitation is taken into account.
We further assume that both A and B are two-level systems.
When A and B are considered separately, excitation is allowed in both A and B.
However, when A and B is treated as a single system, excitation of A and B are not allowed to happen simultaneously, which will cause a difference in energy.

Another example is non-interacting $\text{H}_2$ molecules, which is usually used to test the size consistency of methods. \cite{h2problem}
CI gives the result that the limiting behaviour of total energy $E$ as N $\rightarrow \infty$ is $E \sim N^{-\frac{1}{2}}$, which is completely unreasonable.

In comparison, Coupled cluster and ADC are size consistent, thus are used much more than CI in calculations.

\subsection{Coupled Cluster}
The CI N-body wavefuntion \ref{CIexcite} can be rewritten as
\begin{equation}
\ket{\Psi_0}=(t_0+T_1+T_2+T_3 \dots)\ket{\Phi_0}
\end{equation}
where the $T$ here are convenient to be expressed as second quantization form:
\begin{equation}
\begin{aligned}
	\hat{T}_{1} &=\sum_{i a} t_{i}^{a} \hat{c}_{a}^{\dagger} \hat{c}_{i}
	\\
	\hat{T}_{2} &=\frac{1}{4} \sum_{i j a b} t_{i j}^{a b} \hat{c}_{a}^{\dagger} \hat{c}_{b}^{\dagger} \hat{c}_{j} \hat{c}_{i}
	\\
	&\dots
	\\
	\hat{T}_{n}&=\left(\frac{1}{n !}\right)^{2} \sum_{i j \ldots a b \ldots}^{n} t_{i j \ldots}^{a b \ldots} \hat{c}_{a}^{\dagger} \hat{c}_{b}^{\dagger} \ldots \hat{c}_{j} \hat{c}_{i}
\end{aligned}
\end{equation}
with $\hat{c}^{\dagger}$ and $\hat{c}$ are creation operator and annihilation operation, respectively.

We have seen this formulation will cause size inconsistency.
Coupled cluster solves this problem by write N-body wavefuntion as
\begin{equation}
\ket{\Psi_0}=e^{t_0+T_1+T_2+T_3 \dots}\ket{\Phi_0}
\end{equation}
or usually
\begin{equation}
\ket{\Psi_0}=e^{T}\ket{\Phi_0}
\end{equation}
by defining
\begin{equation}
T=t_0+T_1+T_2+T_3 \dots
\end{equation}

Schrodinger equation gives
\begin{equation}
H | \Psi_{0} \rangle=H e^{T} | \Phi_{0} \rangle=E e^{T} | \Phi_{0} \rangle
\end{equation}
where the Hamiltonian can also be written as second quantization form
\begin{equation}
\hat{H}=\hat{K}+\hat{V}=\sum k_{p q} c_{p}^{\dagger} c_{q}+\frac{1}{2} \sum V_{p q r s} c_{p}^{\dagger} c_{q}^{\dagger} c_{s} c_{r}
\end{equation}
where K instead of T is used as kinetic part to avoid mixing with the coefficients t.

Thus
\begin{equation}
\begin{array}{l}
{\langle\Phi_{0}|e^{-T} H e^{T}| \Phi_{0}\rangle= E\langle\Phi_{0} | \Phi_{0}\rangle= E}
\\
{\langle\Phi^{*}|e^{-T} H e^{T}| \Phi_{0}\rangle= E\langle\Phi^{*} | \Phi_{0}\rangle= 0}
\end{array}
\end{equation}
where $\ket{\Phi^{*}}$ is any single, double, etc Hartree-Fock excited state, which is orthogonal to the Hartree-Fock ground state.

Then we truncate T to some order n, which is most usually chosen to 2, namely
\begin{equation}
T=t_0+T_1+T_2+ \dots +T_n
\end{equation}

Then we need to determine all the coefficients $t$ in the expressions of $T$ in eq.
Obviously, the required number of equations is equal to the number of variables $t$.
Since the number of degree of freedom of $T_i$ is equal to that of $i$-tuple excited state, we can just choose these equations as loop $\ket{\Phi^{*}}$ through single to n-tuple Hartree-Fock excited states.

Although the expansion of $e^T$ is infinite, only the first few terms have contribution to the final result of
\begin{equation}
\langle\Phi^{*}|e^{-T} H e^{T}| \Phi_{0}\rangle
\end{equation}

This is because all orders of $T$ remove occupied electrons and add virtual electrons.
Thus, the summation of orders of all $T$ in expansion of $e^{-T} H e^{T}$ should be at most $i+2$ if the $\ket{\Phi^{*}}$ here is i-tuple excited state.
The contribution of an additional 2 orders is from $c_{p}^{\dagger} c_{q}^{\dagger} c_{s} c_{r}$ in Hamiltonian.

The resulting equations are a set of non-linear equations which are solved in an iterative manner.
Standard quantum chemistry packages (GAMESS (US), NWChem, ACES II, etc.) solve the CC equations using the Jacobi method and direct inversion of the iterative subspace (DIIS) extrapolation of the t-amplitudes to accelerate convergence.

Unlike CI, CC is size consistent.
To better understand it, we still use the previous two-level systems A and B, CIS doesn't allow the simultaneous excitation of A and B, but in CCS, it is allowed by writing the final wavefuntion as
\begin{equation}
\begin{aligned}
	\ket{\Psi_0}&=e^{T_A+T_B}\ket{\Phi_0}
	\\
	&=(1+T_A+T_B+\frac{1}{2}T_AT_B+\frac{1}{2}T_BT_A)\ket{\Phi_0}
	\\
	&=(1+T_A+T_B+T_AT_B)\ket{\Phi_0}
\end{aligned}
\end{equation}
where $T_A$ and $T_B$ commutes since there is no interaction between A and B.

\subsection{M{\o}ller–Plesset Perturbation Theory}
In quantum mechanics, a common way to describe complicated quantum system is perturbation theory approach.
The idea is to start with a simple unperturbed Hamiltonian for which a mathematical solution is known, and add an additional perturbed Hamiltonian representing a weak disturbance to the system.

The total Hamiltonian is
\begin{equation}
H=H_{0}+\lambda V
\end{equation}

Our goal is to express $E_n$ and $\ket{n}$  in terms of the energy levels and eigenstates of the old Hamiltonian:
\begin{equation}
\begin{aligned}
	E_{n}&=E_{n}^{(0)}+\lambda E_{n}^{(1)}+\lambda^{2} E_{n}^{(2)}+\cdots
	\\
	| n \rangle&=| n^{(0)} \rangle+\lambda | n^{(1)} \rangle+\lambda^{2} | n^{(2)} \rangle+\cdots
\end{aligned}
\end{equation}
where $H_0$ is the unperturbed Hamiltonian, while $V$ is the perturbed Hamiltonian.
$\lambda$ is a dimensionless parameter that can take on values ranging continuously from 0 (no perturbation) to 1 (the full perturbation)

In M{\o}ller–Plesset perturbation theory, the Hartree-Fock Hamiltonian is treated as unperturbed Hamiltonian while the rest part is treated as perturbed Hamiltonian:
\begin{equation}
v=\frac{1}{2} \sum V_{p q r s} c_{p}^{\dagger} c_{q}^{\dagger} c_{s} c_{r}-\sum_{k} V_{r k[s k]} n_{k} c_{r}^{\dagger} c_{s}
\end{equation}
where $n_k=1$ when the orbital k is occupied and $n_k=0$ when unoccupied, and $V_{ab[cd]}=V_{abcd}-V_{abdc}$

This kind of partition is called M{\o}ller–Plesset partition.

Up to second order perturbation theory, the expressions for the energy is
\begin{equation}
E_{n}(\lambda)=E_{n}^{(0)}+\lambda\langle n^{(0)}|v| n^{(0)}\rangle+\lambda^{2} \sum_{k \neq n} \frac{|\langle k^{(0)}|v| n^{(0)}\rangle|^{2}}{E_{n}^{(0)}-E_{k}^{(0)}}+O\left(\lambda^{3}\right)
\end{equation}
where the state $k$ and $n$ here are N-body state.

In fact, the first order contribution is zero:
\begin{equation}
\langle n^{(0)}|v| n^{(0)}\rangle=0
\end{equation}
which means Hartree-Fock energy is already accurate up to the first order, and MP2 is the leading term of the perturbation correction.

By replacing N-body state by Hartree-Fock single states and taking the anticommutation of wavefunction into account, we obtain the expression of MP2:
\begin{equation}
E_{\mathrm{MP} 2}=2 \sum_{i, j, a, b} \frac{\langle\varphi_{i} \varphi_{j}|\hat{v}| \varphi_{a} \varphi_{b}\rangle\langle\varphi_{a} \varphi_{b}|\hat{v}| \varphi_{i} \varphi_{j}\rangle}{\varepsilon_{i}+\varepsilon_{j}-\varepsilon_{a}-\varepsilon_{b}}-\sum_{i, j, a, b} \frac{\langle\varphi_{i} \varphi_{j}|\hat{v}| \varphi_{a} \varphi_{b}\rangle\langle\varphi_{a} \varphi_{b}|\hat{v}| \varphi_{j} \varphi_{i}\rangle}{\varepsilon_{i}+\varepsilon_{j}-\varepsilon_{a}-\varepsilon_{b}}
\end{equation}

Since both unperturbed and perturbed Hamiltonian have correct size scaling, MP2 is also a size consistent method.

\section{Density Functional Theory}

Unlike Post-Hartree-Fock methods, DFT does not start from Hartree-Fock result.
Instead, it uses a totally different approach, starting from the Hohenberg-Kohn theorem. \cite{hktheorem}
The theorem states that for a given ground state electron density distribution $\rho ({\vec{r}})$, the potential $V ({\vec{r})}$ is clearly defined and thus the ground state wave function $\Psi$.

Proof:
Assuming $\ket{\Psi_1}$ is the ground state of Hamiltonian $\hat{H}_1$ with external potential $V_1$, and $E_1$ is its energy.
\begin{equation}
E_{1}=\langle\Psi_{1}|\hat{H}_{1}| \Psi_{1}\rangle=\int V_{1}(\vec{r}) \rho(\vec{r})(\vec{r}) \mathrm{d}^{3} r+\langle\Psi_{1}|(\hat{T}+\hat{U})| \Psi_{1}\rangle
\end{equation}
where $\hat{T}$ is kinetic energy operator while $\hat{U}$ is coulomb operator.

If there is a different potential $V_2$ that leads to different ground state $\ket{\Psi_2}$:
\begin{equation}
E_{1}<\langle\Psi_{2}|\hat{H}_{1}| \Psi_{2}\rangle=\langle\Psi_{2}|\hat{H}_{2}| \Psi_{2}\rangle+\langle\Psi_{2}|\hat{H}_{1}-\hat{H}_{2}| \Psi_{2}\rangle= E_{2}+\int\left(V_{1}(\vec{r})-V_{2}(\vec{r})\right) \rho(\vec{r}) \mathrm{d}^{3} r
\end{equation}
Since potential $V_1$ and $V_2$ are treated on equal footing, the following inequality also satisfies:
\begin{equation}
E_{2}<\langle\Psi_{1}|\hat{H}_{2}| \Psi_{1}\rangle= E_{1}+\int\left(V_{2}(\vec{r})-V_{1}(\vec{r})\right) \rho(\vec{r}) \mathrm{d}^{3} r
\end{equation}
Adding these two inequalities gives:
\begin{equation}
E_{1}+E_{2}<E_{1}+E_{2}
\end{equation}
which means the second potential $V_2$ could not exist.

Thus
\begin{equation}
\Psi_{0}=\Psi[\rho_{0}]
\end{equation}
and
\begin{equation}
E_{0}=E[\rho_{0}]=\langle\Psi[\rho_{0}]|\hat{T}+\hat{V}+\hat{U}| \Psi[\rho_{0}]\rangle
\end{equation}
or
\begin{equation}
E_{s}[\rho]=\langle\Psi_{\mathrm{s}}[\rho]|\hat{T}+\hat{V}_{\mathrm{s}}| \Psi_{\mathrm{s}}[\rho]\rangle
\end{equation}

Thus the Schrodinger equation is
\begin{equation}
\left[-\frac{\hbar^{2}}{2 m} \nabla^{2}+V_{\mathrm{s}}(\vec{r})\right] \varphi_{i}(\vec{r})=\varepsilon_{i} \varphi_{i}(\vec{r})
\end{equation}
where there exist a unique functional $V_s$
\begin{equation}
V_{\mathrm{s}}(\vec{r})=V(\vec{r})+\int \frac{e^{2} \rho_{\mathrm{s}}\left(\vec{r}^{\prime}\right)}{|\vec{r}-\vec{r}^{\prime}|} \mathrm{d}^{3} r^{\prime}+V_{\mathrm{XC}}\left[\rho_{\mathrm{s}}(\vec{r})\right]
\end{equation}
that can give correct ground state density and energy.
Here the $V_{\mathrm{XC}}$ is called the exchange-correlation potential, which includes all the many-body interactions.
Since the Hartree term and $V_{\mathrm{XC}}$ depend on $\rho{\vec{r}}$, the problem of solving the Kohn–Sham equation has to be done in a self-consistent iterative way.

However, for most of the systems except free electron gas \cite{homogeneous}, the exact expression for exchange-correlation functional is unknown.
Thus, approximations and fittings are needed to determine exchange-correlation functional.
Some famous exchange-correlation functional types includes local density approximation (LDA)
\begin{equation}
E_{\mathrm{XC}}^{\mathrm{LDA}}[n]=\int \varepsilon_{\mathrm{XC}}(n) n(\vec{r}) \mathrm{d}^{3} r
\end{equation}
local spin density approximation (LSDA)
\begin{equation}
E_{\mathrm{XC}}^{\mathrm{LSDA}}\left[n_{\uparrow}, n_{\downarrow}\right]=\int \varepsilon_{\mathrm{XC}}\left(n_{\uparrow}, n_{\downarrow}\right) n(\vec{r}) \mathrm{d}^{3} r
\end{equation}
and generalized gradient approximation (GGA)
\begin{equation}
E_{\mathrm{XC}}^{\mathrm{GGA}}\left[n_{\uparrow}, n_{\downarrow}\right]=\int \varepsilon_{\mathrm{XC}}\left(n_{\uparrow}, n_{\downarrow}, \nabla n_{\uparrow}, \nabla n_{\downarrow}\right) n(\vec{r}) \mathrm{d}^{3} r
\end{equation}

Difficulties in expressing the exchange part of the energy can be relieved by including a component of the exact exchange energy calculated from Hartree–Fock theory.
Functionals of this type are known as hybrid functionals, including B3LYP \cite{b3lyp}, PBE0 \cite{pbe0} and HSE \cite{hse}.

\section{Relativistic and Non-adiabatic Quantum Chemistry}
In all above discussion of Hartree-Fock, Post-Hartree-Fock and density functional theory, non-relativity and Born-Oppenheimer assumptions are made.
However, there do exist cases that at least one of them break.

Relativistic effects are also neglected in Hartree-Fock, which is fine in systems that all atoms are light atoms, but can cause problems when heavy atoms are included. \cite{relativ}
Many methods have been suggested to partially or fully consider the relativistic effects, including relativistic density functional theory \cite{reladft}, Douglas-Kroll-Hess approximation \cite{dkh} and exact two component method \cite{x2c}.
Pseudopotential is also usually used by approximating the relativistic effect as an additional potential. \cite{relaqchem}

Although Born-Oppenheimer approximation behaves well in most of the cases, there are some cases that quantum nuclear effect plays a very important role, especially in molecules that hydrogen bond is important. \cite{tomqne}
One of the most effective theoretical method to study quantum nuclear effect is path integral molecular dynamics. \cite{pimd}


\documentclass{documentation}

\DeclareMathOperator{\End}{End}
\DeclareMathOperator{\Aut}{Aut}
\DeclareMathOperator{\isom}{Isom}
\DeclareMathOperator{\Adj}{Adj}
\DeclareMathOperator{\GL}{{\rm GL}}
\DeclareMathOperator{\PGL}{{\rm PGL}}
\newcommand{\pseudo}{\Psi\hspace*{-1mm}\isom}

\title{Tame Genus Package}

\author{Joshua Maglione}
\address{Univerist\"at Bielefeld}
\email{jmaglione@math.uni-bielefeld.de}

\author{Peter A. Brooksbank}
\address{Bucknell University}
\email{pbrooksb@bucknell.edu}

\author{James B. Wilson}
\address{Colorado State University}
\email{James.Wilson@ColoState.Edu}

\date{\today}
\version{2.0}
\copyrightyear{2015--2019}

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

\begin{document}

\frontmatter

\maketitle
\tableofcontents

\mainmatter

\chapter{Introduction}

The goal of this package is to provide \textsc{Magma}~\cite{Magma} with high performance isomorphism tests for groups with tame genus. A group has tame genus if its genus is less than $3$. We include automorphism group constructors, along with canonical signatures. For definitions, theorems, and desriptions of algorithms, the reader should consult~\cite{BMW}.
When appropriate, intrinsics for groups also work for tensors (\texttt{TenSpcElt}).
This package includes a number of intrinsics for automorphism and isomorphism computations, canonical labeling, and constructing random groups of genus 1 or 2 of exponent  $\leq p^2$. The index at the end of the documentation records all intrinsics provided by \textsf{TameGenus}.

The latest versions of \texttt{TensorSpace}~\cite{TensorSpacePackage}, \texttt{StarAlge}~\cite{StarAlge}, and \texttt{Sylver}~\cite{Sylver} are required to use this package.
The URLs are found in the bibliography or in the package \texttt{README.md}. Linux users can use the \texttt{install.sh} or \texttt{update.sh} bash files to install or update dependencies. Note that the \texttt{install.sh} will check for the \texttt{.magmarc} file in the home directory.

\section{Citing \textsf{TameGenus}}
To cite the \textsf{TameGenus} package, please use the following\\
\\
Joshua Maglione, Peter A. Brooksbank, and James B. Wilson, \emph{TameGenus}, version 2.0, GitHub, 2019. (\url{https://github.com/thetensor-space/TameGenus}). \\
\\
For AMSRefs:
\begin{verbatim}
\bib{TameGenusPkg}{misc}{
   author={Maglione, Joshua},
   author={Brooksbank, Peter A.},
   author={Wilson, James B.},
   title={TameGenus},
   publisher={GitHub},
   year={2019},
   edition={version 2.0},
   note={\texttt{https://github.com/thetensor-space/TameGenus}},
}
\end{verbatim}

\section{Verbose Printing and Version}

We have included intrinsics to allow for verbose printing.

\index{SetVerbose}
\begin{intrinsics}
SetVerbose(MonStgElt, RngIntElt) : ->
\end{intrinsics}

\texttt{SetVerbose} is a built in Magma function, but with this package, this intrinsic accepts the string \texttt{"TameGenus"} and an integer in $\{0,1,2\}$. Verbose printing level 0 turns off all printing.
Level 1 will print out what \textsc{Magma} is doing in the \textsf{TameGenus} algorithms, and level 2 will print timings and extra structural information.

\begin{example}[VerbosePrinting]
  We demonstrate the verbose printing by constructing a random genus 2 group of order $3^{20 + 2}$.

\begin{code}
> G := RandomGenus2Group(3, [4, 6, 10]);
> #G eq 3^(4 + 6 + 10 + 2);
true
> Genus(G);
2
\end{code}

With the verbose printing, we can see how long each part of the algorithm takes and the information it obtains about the input.
\begin{code}
> SetVerbose("TameGenus", 1);
> A := TGAutomorphismGroup(G);
Extracting the p-central tensor and computing pseudo-isometries.
Checking the radicals.
        dim(Rad_V) = 0
        dim(Rad_W) = 0
Writing tensor over its centroid.
Tensor has genus 2.
Computing the adjoint algebra.
        dim(Adj) = 40
Decomposing tensor into flat and sloped subtensors.
        Block dims = [ 4, 6, 10 ]
Number of sloped blocks to lift: 3.
Field is small enough, applying Pfaffian method.
Number of flat blocks to lift: 0.
Constructing the isometry group.
   G
   |   Sp ( 2 , 3 ^ 2 )
   *
   |   Sp ( 2 , 3 ^ 3 )
   *
   |   Sp ( 2 , 3 ^ 5 )
   *
   |   3 ^ 0    (unipotent radical)
   1
Constructing automorphism group from pseudo-isometries.
\end{code}
\end{example}

We have included an intrinsic to check which version of \textsf{TameGenus} you have attached in Magma.

\index{TameGenusVersion}
\begin{intrinsics}
TameGenusVersion() : -> MonStgElt
\end{intrinsics}

Returns the version number for the \textsf{TameGenus} package attached in Magma.

\begin{example}[Version]
    We quickly verify that we have the latest version of \textsf{TameGenus}.
\begin{code}
> TameGenusVersion();
2.0
\end{code}
\end{example}

\chapter{Constructors}

We introduce intrinsics to construct nonabelian groups of genus $\leq 2$.
We provide some algorithms to construct random groups, and we make no attempt at asserting any analysis of these algorithms.
In particular, these random constructors may not select groups in a uniform distribution.

\index{TGRandomGroup}
\begin{intrinsics}
TGRandomGroup(q, n, g : parameters) : RngIntElt, RngIntElt, RngIntElt -> GrpPC
    Exponentp : BoolElt : true
\end{intrinsics}

Given $q=p^m$, $n>0$, and $g>0$, returns a $p$-group $G$ with genus $\leq g$ and order $q^{n+g}=p^{m(n+g)}$.
If $q$ is not a prime, then the centroid of the group will be a proper field extension of $\mathbb{F}_p$, containing $\mathbb{F}_q$.
If $\circ: V\times V\rightarrowtail W$ is the commutation tensor of $G$, then $\dim_{\mathcal{C}(\circ)}(V)\leq n$ and $\dim_{\mathcal{C}(\circ)}(W)\leq g$, where $\mathcal{C}(\circ)$ is the centroid of $\circ$. The centroid may strictly contain $\mathbb{F}_q$, in which case the dimensions of $V$ and $W$ divide $n$ and $g$, respectively. It is also possible that the returned group is not directly indecomposable; this may cause other intrinsics to reject such output.
The algorithm is based on the Universal Coefficients Theorem, see \cite{LGM:book}*{Chapter~9} for the statement and proof.
There is one optional parameter: \texttt{Exponentp}.

\begin{description}
\item[\textcolor{blue}{\tt Exponentp}]
The default is \texttt{true}.
Set to \texttt{false} if returned group need not have exponent $p$.
\end{description}

\begin{example}[RandomGenusGroups]
    We construct a random group using the \texttt{TGRandomGroup} constructor. Specifically, we create a group $G$ with exponent $5$ such that $\circ_G$ has centroid containing $K=\mathbb{F}_{5^{7}}$ with genus at most $4$ and where $\dim_K(G/\Phi(G)) = 8$. First, we create the group.
\begin{code}
> G := TGRandomGroup(5^7, 8, 4);
> #G eq 5^(7*(8 + 4));
true
\end{code}

    Now we check properties of the group we created. We expect its genus to be at most 4.
\begin{code}
> Genus(G);
4
\end{code}

    We verify that the commutator tensor (coming from the $p$-central series) has a centroid containing the field of order $5^7$.
\begin{code}
> t := pCentralTensor(G);
> t;
Tensor of valence 3, U2 x U1 >-> U0
U2 : Full Vector space of degree 56 over GF(5)
U1 : Full Vector space of degree 56 over GF(5)
U0 : Full Vector space of degree 28 over GF(5)
> C := Centroid(t);
> Dimension(C);
7
> IsSimple(C);
true
\end{code}
\end{example}

\index{RandomGenus2Group}
\begin{intrinsics}
RandomGenus2Group(q, d : parameters) : RngIntElt, [RngIntElt] -> GrpPC
    Exponentp : BoolElt : true
\end{intrinsics}

Given $q=p^m$ and $d=[d_1, \dots, d_k]$, where $d_i>0$, it returns a genus 2 group $G$ whose commutation tensor $\circ : V\times V\rightarrowtail W$ has centroid $\mathcal{C}(\circ)\cong \mathbb{F}_q$ and whose $\perp$-decomposition has blocks of dimensions $d_1,\dots,d_k$ (over $\mathcal{C}(\circ)$).
If $d_i=1$, then this increases the dimension of the radical of $\circ$ by 1 (over $\mathcal{C}(\circ)$).
There is one optional parameter: \texttt{Exponentp}.

\begin{description}
\item[\textcolor{blue}{\tt Exponentp}]
The default is \texttt{true}.
Set to \texttt{false} if returned group need not have exponent $p$.
\end{description}

\begin{example}[PrescribedBlocks]
    Unlike the \texttt{TGRandomGroup} constructor, if we want to construct a genus 2 group with prescribed block dimensions, we can do this with \texttt{RandomGenus2Group}. If we want an elementary abelian direct factor, we can append a sequence of $1$s whose sum is the rank of such a factor. We construct a genus 2 group $G$ with an indecomposable blocks of dimensions $10$, $7$, $4$, $4$, and $1$. Therefore, $G\cong H\times \mathbb{Z}/(p)$, where $H$ is direct indecomposable and of order $7^{25+2}$.
\begin{code}
> G := RandomGenus2Group(7, [10, 7, 4, 4, 1]);
> #G eq 7^(10 + 7 + 4 + 4 + 1 + 2);
true
\end{code}

    We can see these blocks with the genus 2 signature of the group.
\begin{code}
> S := TGSignature(G);
> S;
[* <7, 25, 2>, <1, 0>,
    [ 7 ],
    [*
        [ 1, 5, 5 ],
        [ 1, 4, 6 ],
        [ 1, 5, 1, 3, 6, 6 ]
    *]
*]
\end{code}

To learn how to read the above data, see the documentation for
\texttt{TGSignature}. This shows that $\circ_G$ has a $1$-dimensional radical
and is full. Moreover, it is $\perp$-decomposable as a flat $7$-dimensional
block with three sloped blocks. The corresponding Pfaffians (unique up to
$\mathrm{PGL}(2, 7)$) are
\begin{align*}
    & x^2 + 5xy + 5y^2, & & x^2 + 4xy + 6y^2, & & x^5 + 5x^4y + x^3y^2 + 3x^2y^3 + 6xy^4 + 6y^5.
\end{align*}
\end{example}

\index{RandomGenus1Group}
\begin{intrinsics}
RandomGenus1Group(q, d, r : parameters) : RngIntElt, RngIntElt, RngIntElt -> GrpPC
    Exponentp : BoolElt : true
\end{intrinsics}

Given $q=p^m$, $d>0$, and $r\geq 0$, it returns a group $G$ with genus 1 and of order $q^{2d+r+1}$.
The center of $G$ has order $q^{r+1}$, and $G$ is $m(2d+r)$-generated.
There is one optional parameter: \texttt{Exponentp}.

\begin{description}
\item[\textcolor{blue}{\tt Exponentp}]
The default is \texttt{true}.
Set to \texttt{false} if returned group need not have exponent $p$.
\end{description}

\begin{example}[Heisenbergs]
    The classic Heisenberg group over a field is an example of a genus 1 group, and one can generalize this construction in a number of ways. We will create the following matrix group, as a polycyclic group, over $\mathbb{F}_{81}$:
    \begin{align*}
        G &= \left\{\begin{bmatrix}
            1 & * & * & * \\
              & 1 & 0 & * \\
              &   & 1 & * \\
              &   &   & 1
        \end{bmatrix}\right\}
    \end{align*}
\begin{code}
> G := RandomGenus1Group(81, 2, 0);
> #G eq 81^(2*2 + 1);
true
\end{code}

    We will verify that that $G$ is genus 1, but first note that the derived subgroup is isomorphic to $(\mathbb{Z}/(3))^4$.
\begin{code}
> D := DerivedSubgroup(G);
> IsElementaryAbelian(D);
true
> #D eq 3^4;
true
\end{code}

    Although the underlying field $\mathbb{F}_{81}$ is hidden within the relations of the polycyclic presentation, we can still determine it and compute the genus over this larger field.
\begin{code}
> Genus(G);
1
\end{code}
\end{example}

\index{Genus2Group}
\begin{intrinsics}
Genus2Group(f) : RngUPolElt -> GrpPC
Genus2Group(f) : RngMPolElt -> GrpPC
\end{intrinsics}

Given either a univariate or homogeneous multivariate polynomial in $x$ (and $y$) over $\mathbb{F}_q$, it returns a group $G$ whose commutator $\mathbb{F}_q$-tensor has a Pfaffian equivalent to $f$.

\begin{example}[Pfaffians]
    We take the constructor \texttt{RandomGenus2Group} and specialize to sloped genus 2 groups. We will construct the genus 2 group $G$ whose (univariate) Pfaffian is equivalent to $f(x) = x^3(x-1)^2(x-2)$ in $\mathbb{F}_{9}[x]$. Therefore, we expect $|G|=9^{2\cdot 6 + 2}$.
\begin{code}
> P<x> := PolynomialRing(GF(9));
> f := x^3*(x-1)^2*(x-2);
> G := Genus2Group(f);
> #G eq 9^(2*6 + 2);
true
\end{code}

    The genus 2 signature will reveal the correct block structure. All six $\perp$-indecomposable subspaces will be $2$-dimensional, but they will partition similar to the splitting behavoir of the polynomial $f$.
\begin{code}
> S := TGSignature(G);
> S[4];
[*
    [ 1, 1 ],
    [ 1, 0, 0 ],
    [ 0, 0, 0, 1 ]
*]
\end{code}

    This shows that homogenization of $f$ is equivalent to the polynomial $g(x,y) = x^2y^3(x+y)$.
\end{example}

\section{Direct indecomposability}

The definition of genus requires knowing the (direct) indecomposable factors of a group $G$. Although we do not have intrinsics to produce a list of subgroups that are indecomposable, we have an efficient test to decide if the given nilpotent group is indecomposable. There is an analog for tensors as well. These are based off of algorithms from~\cite{Wilson:decomposable}.

\index{IsIndecomposable!groups}\index{IsIndecomposable!tensors}
\begin{intrinsics}
IsIndecomposable(G) : GrpPC -> BoolElt
IsIndecomposable(t) : TenSpcElt -> BoolElt
\end{intrinsics}

Given either a group $G$ or a tensor $t$, decide if the given object is indecomposable.

\noindent \textbf{Warning:} We make no claim that the intrinsics in this package will accept input that return \texttt{false} from \texttt{IsIndecomposable}. There are indeed cases where the group or tensor is not indecomposable (e.g.\ nontrivial radical) where all the intrinsics will work fine.

\begin{example}[Decomposable]
    We can create a decomposable genus 2 group from the above constructors. For example, the group $G$ with the Pfaffian $xy$ will be decomposable.
\begin{code}
> P<x, y> := PolynomialRing(GF(7), 2);
> f := x*y;
> G := Genus2Group(f);
> G;
GrpPC : G of order 117649 = 7^6
PC-Relations:
G.3^G.1 = G.3 * G.5,
G.4^G.2 = G.4 * G.6
> IsIndecomposable(G);
false
\end{code}

    This example also shows that \texttt{TGRandomGroup} may return a group which is directly decomposable.
\end{example}

\begin{example}[DirectNotCentral]
    Note that the commutator tensor of a group can be directly indecomposable while still having a nontrivial $\perp$-decomposition. We create the directly indecomposable group $G$ which is a central product of two genus 2 groups.
\begin{code}
> G := RandomGenus2Group(5, [3, 4]);
> #G eq 5^(3 + 4 + 2);
true
> IsIndecomposable(G);
true
\end{code}

    We can observe the central factors from the genus 2 signature of the group.
\begin{code}
> TGSignature(G);
[* <5, 7, 2>, <0, 0>,
    [ 3 ],
    [*
        [ 1, 0, 2 ]
    *]
*]
\end{code}
\end{example}

\section{Genus}

\index{Genus!groups}\index{Genus!tensors}
\begin{intrinsics}
Genus(G) : GrpPC -> RngIntElt
Genus(t) : TenSpcElt -> RngIntElt
\end{intrinsics}

Given an indecomposable $p$-group $G$, it returns the genus of $G$.
That is, the rank of $[G,G]$ over the centroid.
For an indecomposable tensor $t: V\times V\rightarrowtail W$, it returns the rank of $W$ over its centroid.

\begin{example}[Genus]\label{ex:Genus}
    We will determine the genus of some groups in the Small Group library. First, let $G$ be the group of order $3^6$ with ID number 440. Its derived subgroup is isomorphic to $(\mathbb{Z}/(3))^2$, and $G$ is genus 2.
\begin{code}
> G := SmallGroup(3^6, 440);
> #DerivedSubgroup(G) eq 3^2;
true
> IsElementaryAbelian(DerivedSubgroup(G));
true
> Genus(G);
2
\end{code}

    Let $H$ be the group of order $3^6$ with ID number 469. Its derived subgroup is isomorphic to $(\mathbb{Z}/(3))^2$ also, but $H$ is genus 1.
\begin{code}
> H := SmallGroup(3^6, 469);
> #DerivedSubgroup(H) eq 3^2;
true
> IsElementaryAbelian(DerivedSubgroup(H));
true
> Genus(H);
1
\end{code}

    We can see this difference in multiple ways. If we extract the commutator tensor from both groups, one will be bilinear over a quadratic field extension where the other is not. The algebra that records this is the centroid of a bilinear map.
\begin{code}
> s := pCentralTensor(G);
> t := pCentralTensor(H);
> C_G := Centroid(s);
> C_H := Centroid(t);
> C_G;
Matrix Algebra of degree 6 with 2 generators over GF(3)
> C_H;
Matrix Algebra of degree 6 with 2 generators over GF(3)
\end{code}

    The centroid associated to the tensor $s$ is $2$-dimensional but with a nontrivial Jacobson radical. The centroid associated to the tensor $t$ is $2$-dimensional and a simple $\mathbb{F}_3$-algebra.
\begin{code}
> Dimension(C_G);
2
> Dimension(C_H);
2
> WedderburnDecomposition(C_G);
Matrix Algebra of degree 6 with 1 generator over GF(3)
Matrix Algebra of degree 6 with 1 generator over GF(3)
> IsSimple(C_H);
true
\end{code}
\end{example}

\index{IsTameGenusGroup}
\begin{intrinsics}
IsTameGenusGroup(G) : Group -> BoolElt
\end{intrinsics}

Decides if the functions in the \textsf{TameGenus} package can be applied to the given group $G$.

\index{IsTameGenusTensor}
\begin{intrinsics}
IsTameGenusTensor(t) : TenSpcElt -> BoolElt
\end{intrinsics}

Decides if the functions in the \textsf{TameGenus} package can be applied to the given tensor $t$.

\begin{example}[NonExample]
    We create a group that is not covered by the \textsf{TameGenus} package. From the Genus example, see Example~\ref{ex:Genus}, the small groups of order $3^6$ with IDs 440 and 469 both have tame genus: 2 and 1 respectively. The direct product of the two groups has genus 2, but because the group is not directly decomposable, the current implementation of \textsf{TameGenus} cannot handle it.
\begin{code}
> H1 := SmallGroup(3^6, 440);
> H2 := SmallGroup(3^6, 469);
> G := DirectProduct(H1, H2);
> G;
GrpPC : G of order 531441 = 3^12
PC-Relations:
    G.2^G.1 = G.2 * G.5,
    G.3^G.1 = G.3 * G.6,
    G.3^G.2 = G.3 * G.5,
    G.4^G.1 = G.4 * G.5,
    G.8^G.7 = G.8 * G.11,
    G.9^G.7 = G.9 * G.12,
    G.9^G.8 = G.9 * G.11^2 * G.12,
    G.10^G.7 = G.10 * G.11 * G.12,
    G.10^G.8 = G.10 * G.11
> IsTameGenusGroup(G);
false
\end{code}
\end{example}

\begin{example}[AllTheSmallGroups]
    We can use the \texttt{IsTameGenusGroup} and \texttt{IsTameGenusTensor} to filter large databases down to the ones covered by \textsf{TameGenus}. We do that here with the Small Group library for groups of order $3^6$, and we find there are seven such groups.
\begin{code}
> G2_SG := [*G : G in SmallGroups(3^6) | IsTameGenusGroup(G)*];
> #G2_SG;
7
\end{code}

    We further filter these groups based on their genus, and we find there are three groups of positive genus (and one abelian group).
\begin{code}
> G1 := [*G : G in TG_SG | Genus(G) eq 1*];
> G2 := [*G : G in TG_SG | Genus(G) eq 2*];
> #G1;
3
> #G2;
3
\end{code}

    Now we determine the tame genus signatures to show that all these groups yield different signatures. We first consider the genus 1 groups.
\begin{code}
> for G in G1 do
for>     TGSignature(G);
for> end for;
[* <9, 2, 1>, <0, 0>, [* *], [* *] *]
[* <3, 2, 1>, <3, 0>, [* *], [* *] *]
[* <3, 4, 1>, <1, 0>, [* *], [* *] *]
\end{code}

    The genus 2 groups have the following signatures.
\begin{code}
> for G in G2 do
for>     TGSignature(G);
for> end for;
[* <3, 3, 2>, <1, 0>,
    [ 3 ],
    [* *]
*]
[* <3, 4, 2>, <0, 0>,
    [],
    [*
        [ 0, 0, 1 ]
    *]
*]
[* <3, 4, 2>, <0, 0>,
    [],
    [*
        [ 1, 0 ],
        [ 0, 1 ]
    *]
*]
\end{code}
\end{example}

\chapter{Isomorphism}

We have two intrinsics for deciding isomorphism: one for groups and one for tensors.

\index{TGIsIsomorphic}
\begin{intrinsics}
TGIsIsomorphic(G, H : parameters) : GrpPC, GrpPC -> BoolElt
    Cent : BoolElt : true
    Constructive : BoolElt : true
    Method : RngIntElt : 0
\end{intrinsics}

Given class $\leq 2$, exponent $p$, indecomposable $p$-groups $G$ and $H$ of genus $\leq 2$, decides if $G\cong H$.
If $G\cong H$, then an isomorphism is provided unless specified otherwise.
Currently, this does not work for $p=2$. When the groups are decomposable, the intrinsic might decide isomorphism (e.g.\ when the centers properly contain the derived group), or it might return an error. In particular, an incorrect decision should not occur.
There are three optional parameters: \texttt{Cent}, \texttt{Constructive}, and \texttt{Method}.

\begin{description}
\item[\textcolor{blue}{\tt Cent}]
This parameter is a flag for the algorithm to rewrite the tensors over their centroids. In order to rewrite over the centroid, we assume the centroid is a local ring, see~\cite{TensorSpacePackage} for details. The default is \texttt{true}, so by default, the algorithm computes the centroid and rewrites the tensor over the residue field.
If this step should be avoided, set to \texttt{false} to save some time.
\item[\textcolor{blue}{\tt Constructive}]
The default is \texttt{true}.
Set to \texttt{false} if an explicit isomorphism is not needed.
\item[\textcolor{blue}{\tt Method}]
The default is $0$, and any input from $\{ 0,1,2\}$ is acceptable.
This will set the method for handling the sloped part of the tensor.
If the adjoint-tensor method should be used, set to $1$. If the Pfaffian method should be used, set to $2$. The default will try to find the optimal method based on the input; this is not yet optimally tuned but is generally good.
\end{description}

\begin{example}[IsomorphismTesting]
    We will create an isomorphic pair of groups in two different ways, and then we will construct an isomorphism between the two. This example can be seen as verifying Theorem~1.1 of~\cite{LM:semi-extraspecial}. We construct groups $G$ and $H$ from two random irreducible cubic polynomials in $\mathbb{F}_{67}[x]$.
\begin{code}
> f := RandomIrreduciblePolynomial(GF(67), 3);
> g := RandomIrreduciblePolynomial(GF(67), 3);
> f, g;
$.1^3 + 36*$.1^2 + 26*$.1 + 33
$.1^3 + 57*$.1^2 + 24*$.1 + 65
> G := Genus2Group(f);
> H := Genus2Group(g);
\end{code}

    The default method, in this case, will run the adjoint-tensor method. We can see it running if we turn on verbose printing.
\begin{code}
> SetVerbose("TameGenus", 1);
> isomorphic, phi := TGIsIsomorphic(G, H);
Extracting p-central tensors and deciding pseudo-isometry.
Checking the radicals.
        dim(Rad_V) = 0
        dim(Rad_W) = 0
Checking the radicals.
        dim(Rad_V) = 0
        dim(Rad_W) = 0

Writing tensor over its centroid.

Writing tensor over its centroid.

Computing the adjoint algebra.
        dim(Adj_s) = 12
        dim(Adj_t) = 12

Computing the adjoint algebra.

Genus 2 case.

Decomposing tensors into flat and sloped subtensors.
        Block dims = [ 6 ]

PGammaL is larger than symmetric group, applying adjoint-tensor method.
\end{code}

    We see that the two groups are isomorphic, and $\phi$ is such an isomorphism.
\begin{code}
> isomorphic;
true
> phi;
Homomorphism of GrpPC : G into GrpPC : H induced by
    G.1 |--> H.1 * H.2^41 * H.3^30 * H.4^58 * H.5^43 * H.6^30
    G.2 |--> H.1^53 * H.2^4 * H.3^34 * H.4^54 * H.5^6 * H.6^25
    G.3 |--> H.1^5 * H.2^7 * H.3^49 * H.4^52 * H.5^21 * H.6^7
    G.4 |--> H.1^30 * H.2^4 * H.3^17 * H.4^53 * H.5^40 * H.6^9
    G.5 |--> H.1^14 * H.2^21 * H.3^30 * H.4^24 * H.5^38 * H.6^34
    G.6 |--> H.1^47 * H.2^46 * H.3^66 * H.4^65 * H.5^30 * H.6^30
    G.7 |--> H.7^10 * H.8^18
    G.8 |--> H.7^54 * H.8^12
\end{code}

    If we want to run the Pfaffian test, we set the \texttt{Method} to 2. This method is considerably slower for these groups.
\begin{code}
> isomorphic, phi2 := TGIsIsomorphic(G, H : Method := 2);
Extracting p-central tensors and deciding pseudo-isometry.
Checking the radicals.
        dim(Rad_V) = 0
        dim(Rad_W) = 0
Checking the radicals.
        dim(Rad_V) = 0
        dim(Rad_W) = 0

Writing tensor over its centroid.

Writing tensor over its centroid.

Computing the adjoint algebra.
        dim(Adj_s) = 12
        dim(Adj_t) = 12

Computing the adjoint algebra.

Genus 2 case.

Decomposing tensors into flat and sloped subtensors.
        Block dims = [ 6 ]

Method set to Pfaffian.
> phi2;
Homomorphism of GrpPC : G into GrpPC : H induced by
    G.1 |--> H.1^47 * H.2^54 * H.3^54
    G.2 |--> H.1^63 * H.2^33 * H.3^15
    G.3 |--> H.1^26 * H.2^3 * H.3^60
    G.4 |--> H.4^44 * H.5^61 * H.6^16
    G.5 |--> H.4^66 * H.5^26 * H.6^36
    G.6 |--> H.4^57 * H.5^6 * H.6^30
    G.7 |--> H.7^62 * H.8^42
    G.8 |--> H.7^18 * H.8^58
\end{code}
\end{example}

\index{TGIsPseudoIsometric}
\begin{intrinsics}
TGIsPseudoIsometric(s, t : parameters) : TenSpcElt, TenSpcElt -> BoolElt, Hmtp
    Cent : BoolElt : true
    Constructive : BoolElt : true
    Method : RngIntElt : 0
\end{intrinsics}

\color{black}
Given indecomposable, alternating tensors $s, t : V\times V \rightarrowtail W$, where $V$ and $W$ are $\mathbb{F}_q$-vector spaces, decide if $s$ is pseudo-isometric to $t$.
If so, a pseudo-isometry is also returned as a homotopism.
Currently this does not work for even $q$.
When the tensors are decomposable, the intrinsic might decide isomorphism (e.g.\ when the tensors have nontrivial radical), or it might return an error. In particular, an incorrect decision should not occur.
There are three optional parameters: \texttt{Cent}, \texttt{Constructive}, and \texttt{Method}.

\begin{description}
\item[\textcolor{blue}{\tt Cent}]
This parameter is a flag for the algorithm to rewrite the tensors over their centroids. In order to rewrite over the centroid, we assume the centroid is a local ring, see~\cite{TensorSpacePackage} for details. The default is \texttt{true}, so by default, the algorithm computes the centroid and rewrites the tensor over the residue field.
If this step should be avoided, set to \texttt{false} to save some time.
\item[\textcolor{blue}{\tt Constructive}]
The default is \texttt{true}.
Set to \texttt{false} if an explicit isomorphism is not needed.
\item[\textcolor{blue}{\tt Method}]
The default is $0$, and any input from $\{ 0,1,2\}$ is acceptable.
This will set the method for handling the sloped part of the tensor.
If the adjoint-tensor method should be used, set to $1$. If the Pfaffian method should be used, set to $2$. The default will try to find the optimal method based on the input; this is not yet optimally tuned but is generally good.
\end{description}

\begin{example}[PseudoIsometries]
    A pair of alternating matrices determines a tensor of tame genus. We will construct a pair of pseudo-isometric tensors by applying a change of basis isotopism. This is essentially how Experiment A from~\cite{BMW} was conducted. Generating random $100\times 100$ matrices over $\mathbb{F}_3$, we build two tensors $s,t : \mathbb{F}_3^{50} \times \mathbb{F}_3^{50}\rightarrowtail\mathbb{F}_3^2$.
\begin{code}
> M := RandomMatrix(GF(3), 50, 50);
> N := RandomMatrix(GF(3), 50, 50);
> Forms1 := [M - Transpose(M), N - Transpose(N)];
> s := Tensor(Forms1, 2, 1);
> s;
Tensor of valence 3, U2 x U1 >-> U0
U2 : Full Vector space of degree 50 over GF(3)
U1 : Full Vector space of degree 50 over GF(3)
U0 : Full Vector space of degree 2 over GF(3)
> IsAlternating(s);
true
\end{code}

    Now we construct a random invertible co-homotopism $\varphi$ such that $\varphi_2\in \GL(50, 3)$ and $\varphi_0\in\GL(2, 3)$. We define a new and pseudo-isometric tensor $t=s^{\varphi}$ in this way.
\begin{code}
> X := Random(GL(50, 3));
> Y := Random(GL(2, 3));
> Maps := [*X, X, Y*];
> H := Homotopism(Maps, CohomotopismCategory(3));
> t := s @ H;
> t;
Tensor of valence 3, U2 x U1 >-> U0
U2 : Full Vector space of degree 50 over GF(3)
U1 : Full Vector space of degree 50 over GF(3)
U0 : Full Vector space of degree 2 over GF(3)
> s eq t;
false
\end{code}

    We verify that both $s$ and $t$ are pseudo-isometric, and since we do not need to write these tensors over their centroid, we avoid that step by setting \texttt{Cent} to \texttt{false}.
\begin{code}
> pisometric, Phi := TGIsPseudoIsometric(s, t : Cent := false);
> pisometric;
true
> Phi.0;
[0 1]
[2 2]
\end{code}
\end{example}

\chapter{Automorphism groups}

Like with isomorphisms, we have two distinct automorphism intrinsics.

\index{TGAutomorphismGroup}
\begin{intrinsics}
TGAutomorphismGroup(G : parameters) : GrpPC -> GrpAuto
    Cent : BoolElt : true
    Method : RngIntElt : 0
    Mat : BoolElt : false
\end{intrinsics}

Given an indecomposable $p$-group $G$, of class $\leq 2$, exponent $p$, and genus $\leq 2$, return $\Aut(G)$.
This currently does not work with $p=2$. When $G$ is decomposable, the intrinsic might construct $\Aut(G)$ (e.g.\ when the center properly contains the derived group), or it might return an error. In particular, the wrong (or incomplete) automorphism group should not be returned.
This intrinsic provides three optional parameters: \texttt{Cent}, \texttt{Method}, and \texttt{Mat}.

\begin{description}
\item[\textcolor{blue}{\tt Cent}]
This parameter is a flag for the algorithm to rewrite the tensors over their centroids. In order to rewrite over the centroid, we assume the centroid is a local ring, see~\cite{TensorSpacePackage} for details. The default is \texttt{true}, so by default, the algorithm computes the centroid and rewrites the tensor over the residue field.
If this step should be avoided, set to \texttt{false} to save some time.
\item[\textcolor{blue}{\tt Method}]
The default is $0$, and any input from $\{ 0,1,2\}$ is acceptable.
This will set the method for handling the sloped part of the tensor.
If the adjoint-tensor method should be used, set to $1$. If the Pfaffian method should be used, set to $2$. The default will try to find the optimal method based on the input; this is not yet optimally tuned but is generally good.
\item[\textcolor{blue}{\tt Mat}]
The default is \texttt{false}. When \texttt{true}, the output will be a linear representation of the automorphism group. The row vectors of the matrix correspond to the polycyclic vectors from the polycyclic presentation.
\end{description}

\begin{example}[FlatIndecomposable]
    We build a flat indecomposable genus 2 $p$-group $G$ and construct its automorphism group. We know that $\Aut(G)$ maps surjectivity onto $\GL(2, p)$, so we will verify that $|\Aut(G)|$ is divisible by $(p^2-1)(p^2-p)$. This corresponds to the quotient of the pseudo-isometry group by the isometry group.
\begin{code}
> p := 541;
> G := RandomGenus2Group(p, [29]);
> #G eq p^(29 + 2);
true
> A := TGAutomorphismGroup(G);
> IsDivisibleBy(#A, #GL(2, p));
true
\end{code}

    The isometry group of the corresponding commutator tensor has an elementary abelian unipotent radical of rank $28$, and so is isomorphic to $(\mathbb{Z}/(p))^{28}\rtimes \mathrm{GL}(1, p)$, as seen in~\cite{BW:isometry}. Therefore, we can verify that we have constructed all automorphisms as
    \begin{align*}
        |\Aut(G)| &= (p - 1)p^{28} \cdot (p^2-1)(p^2-p) \cdot p^{29\cdot 2}.
    \end{align*}
\begin{code}
> #A eq (p - 1)*p^28 * (p^2 - 1)*(p^2 - p) * p^(29*2);
true
\end{code}
\end{example}

\index{TGPseudoIsometryGroup}
\begin{intrinsics}
TGPseudoIsometryGroup(t : parameters) : TenSpcElt -> GrpMat
    Cent : BoolElt : true
    Method : RngIntElt : 0
\end{intrinsics}

Given an indecomposable, alternating tensor $t : V \times V \rightarrowtail W$, where $V$ and $W$ are $\mathbb{F}_q$-vector spaces, return the pseudo-isometry group $\pseudo(t)\leq \GL(V)\times \GL(W)$.
This currently does not work for even $q$. When $t$ is decomposable, the intrinsic might construct $\pseudo(t)$ (e.g.\ when $t$ has a nontrivial radical), or it might return an error. In particular, the wrong (or incomplete) pseudo-isometry group should not be returned.
This intrinsic provides two optional parameters: \texttt{Cent} and \texttt{Method}.

\begin{description}
\item[\textcolor{blue}{\tt Cent}]
This parameter is a flag for the algorithm to rewrite the tensors over their centroids. In order to rewrite over the centroid, we assume the centroid is a local ring, see~\cite{TensorSpacePackage} for details. The default is \texttt{true}, so by default, the algorithm computes the centroid and rewrites the tensor over the residue field.
If this step should be avoided, set to \texttt{false} to save some time.
\item[\textcolor{blue}{\tt Method}]
The default is $0$, and any input from $\{ 0,1,2\}$ is acceptable.
This will set the method for handling the sloped part of the tensor.
If the adjoint-tensor method should be used, set to $1$. If the Pfaffian method should be used, set to $2$. The default will try to find the optimal method based on the input; this is not yet optimally tuned but is generally good.
\end{description}

\begin{example}[Extensions]
    For $K$ vector spaces $V$ and $W$, we create a genus 2 alternating tensor $t: V \times V\rightarrowtail W$ such that $t$ is bilinear over an extension field $E/K$ and $\dim_E(W)=2$. One way to do this is via the constructor \texttt{RandomGenus2Group}.
\begin{code}
> G := RandomGenus2Group(3^2, [6]);
> t := pCentralTensor(G);
> t;
Tensor of valence 3, U2 x U1 >-> U0
U2 : Full Vector space of degree 12 over GF(3)
U1 : Full Vector space of degree 12 over GF(3)
U0 : Full Vector space of degree 4 over GF(3)
> Genus(t);
2
\end{code}

    The Pfaffian of $t$ is an irreducible cubic over $\mathbb{F}_9$, so computing its pseudo-isometry group may contain elements of $\mathrm{Gal}(\mathbb{F}_9)$.
\begin{code}
> PI := TGPseudoIsometryGroup(t);
> Random(PI);
[0 1 0 0 0 2 1 1 0 2 1 0 0 0 0 0]
[2 0 0 0 1 0 0 2 1 0 1 2 0 0 0 0]
[1 1 0 0 0 1 1 1 0 0 2 1 0 0 0 0]
[0 2 0 0 2 0 0 2 0 0 1 1 0 0 0 0]
[1 2 2 0 0 2 2 2 1 0 0 0 0 0 0 0]
[2 2 2 1 1 0 0 1 1 2 0 0 0 0 0 0]
[2 2 2 0 1 0 1 0 2 2 1 2 0 0 0 0]
[0 1 2 1 1 2 1 2 0 1 2 2 0 0 0 0]
[2 0 1 0 2 2 2 1 1 1 0 0 0 0 0 0]
[2 1 1 2 0 1 1 1 0 2 0 0 0 0 0 0]
[0 2 0 1 2 2 1 1 0 1 1 0 0 0 0 0]
[1 0 2 0 0 1 0 2 2 0 1 2 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0]
[0 0 0 0 0 0 0 0 0 0 0 0 2 0 1 2]
[0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0]
> Factorization(#PI);
[ <2, 8>, <3, 7>, <5, 1>, <7, 1>, <13, 1>, <73, 1> ]
\end{code}

    Indeed, the pseudo-isometry group may not be linear over the centroid but semi-linear. To see the discrepancy, we rewrite $t$ over its centroid and determine its pseudo-isometry group. We see that $\pseudo(t)$ is strictly semi-linear over $\mathbb{F}_9$, as there exists a Galois involution.
\begin{code}
> s := TensorOverCentroid(t);
> s;
Tensor of valence 3, U2 x U1 >-> U0
U2 : Full Vector space of degree 6 over GF(3^2)
U1 : Full Vector space of degree 6 over GF(3^2)
U0 : Full Vector space of degree 2 over GF(3^2)
> PI_C := TGPseudoIsometryGroup(s);
> Random(PI_C);
[    1 $.1^7     1 $.1^2 $.1^2 $.1^5     0     0]
[  $.1     2 $.1^7 $.1^3 $.1^6 $.1^5     0     0]
[$.1^7 $.1^2 $.1^7     1 $.1^6 $.1^2     0     0]
[$.1^7 $.1^7 $.1^7 $.1^3 $.1^7     1     0     0]
[    2 $.1^6 $.1^3 $.1^2 $.1^3     0     0     0]
[$.1^7   $.1 $.1^7 $.1^6 $.1^6 $.1^7     0     0]
[    0     0     0     0     0     0     2 $.1^7]
[    0     0     0     0     0     0 $.1^3 $.1^5]
> Factorization(#PI_C);
[ <2, 7>, <3, 7>, <5, 1>, <7, 1>, <13, 1>, <73, 1> ]
\end{code}
\end{example}

\chapter{Canonical Labeling}

\index{TGSignature!groups}\index{TGSignature!tensors}
\begin{intrinsics}
TGSignature(G) : GrpPC -> List
TGSignature(t) : TenSpcElt -> List
\end{intrinsics}

Given an indecomposable group or tensor of tame genus, returns the canonical tame genus signature as a list.
The list has four entries. For inputs with genus $\leq 1$, the last two entries will be empty lists.
\begin{enumerate}
    \item The first is a triple of three integers $(q, d, e)$ such that associated fully nondegenerate tensor of the (commutator) tensor has the form $\mathbb{F}_q^d\times \mathbb{F}_q^d\rightarrowtail \mathbb{F}_q^e$. Here, $\mathbb{F}_q$ is the Galois field of the residue field of the centroid, which is a local ring. Therefore, $\mathbb{F}_q = \mathrm{GF}(q)$.
    \item The second entry is a pair of integers $(r, c)$, where $r$ is the dimension of the radical of the (commutator) tensor and $c$ is the codimension of the image in the codomain.
    \item The third entry is a sequence of odd integers corresponding to the dimensions of the flat indecomposable spaces.
    \item The fourth and last entry is a list sequences in $\mathbb{F}_q$ of possibly different lengths. A sequence $[c_1,\dots, c_{d+1}]$ in the second entry corresponds to the coefficients of the homogeneous polynomial in $x$ and $y$ in degree $d$:
    \[ c_1x^d + c_2 x^{d-1}y + c_3 x^{d-2}y^2 + \cdots + c_{d+1}y^d. \]
\end{enumerate}
Because this is a canonical label, two groups (or tensors) are isoclinic (or pseudo-isometric) if, and only if, their genus 2 signatures are equal. Therefore, isoclinism or pseudo-isometry is determined by (honest) equality of lists.

When the input is decomposable, the intrinsic might construct the signature (e.g.\ when the tensor has a nontrivial radical), or it might return an error. In particular, the wrong signature should not be returned.

\begin{example}[ManyBlocks]
    We construct a genus 2 group $G$ with many sloped and flat blocks.
\begin{code}
> blocks := [1, 1, 1, 2, 2, 3, 3, 5, 6];
> G := RandomGenus2Group(9, blocks);
> #G eq 9^(&+blocks + 2);
true
\end{code}

    We expect the commutator tensor from $G$ to have a $3$-dimensional (over $\mathbb{F}_9$) radical, and to have data corresponding to the blocks above.
\begin{code}
> TGSignature(G);
[* <9, 21, 2>, <6, 0>,
    [ 3, 3, 5 ],
    [*
        [ 0, 1 ],
        [ 1, 1 ],
        [ 1, 2, 2, 2 ]
    *]
*]
\end{code}

    The first entry of this list tells us that the associated fully nondegenerate tensor of $G$ has the frame $\mathbb{F}_9^{21}\times\mathbb{F}_9^{21}\rightarrowtail \mathbb{F}_9^2$. The second entry says that the commutator tensor from $G$ has $6$-dimensional radical over $\mathbb{F}_3$, the field for which the commutator tensor was initially defined over. In other words, $G\cong H\times \mathbb{F}_9^3$. The third entry tells us that $H$ is a central product of six indecomposable groups: three flats of orders $9^{3+2}$, $9^{3+2}$, and $9^{5+2}$, and three sloped with Pfaffians in $\mathbb{F}_9[x,y]$ equivalent to
    \begin{align*}
        & y, & & x + y, & & x^3 + 2x^2y + 2xy^2 + 2y^3.
    \end{align*}
\end{example}

\begin{example}[MoreSmallGroups]
    We run through all the small groups of order $3^7$ and determine their tame genus signatures. There are $9310$ such groups, and $10$ of them are covered by \textsf{TameGenus}.
\begin{code}
> TG_SG := SmallGroupProcess(3^7, IsTameGenusGroup);
>
> repeat
repeat>     G := Current(TG_SG);
repeat>     _, ID := CurrentLabel(TG_SG);
repeat>     print "Small group ID:", ID;
repeat>     TGSignature(G);
repeat>     Advance(~TG_SG);
repeat> until IsEmpty(TG_SG);
\end{code}

    The loop yields the following output.
\begin{code}
Small group ID: 9106
[* <3, 3, 2>, <2, 0>,
    [ 3 ],
    [* *]
*]
Small group ID: 9107
[* <3, 4, 2>, <1, 0>,
    [],
    [*
        [ 1, 0 ],
        [ 0, 1 ]
    *]
*]
Small group ID: 9108
[* <3, 4, 2>, <1, 0>,
    [],
    [*
        [ 0, 0, 1 ]
    *]
*]
Small group ID: 9109
[* <9, 2, 1>, <1, 0>, [* *], [* *] *]
Small group ID: 9110
[* <3, 5, 2>, <0, 0>,
    [ 3 ],
    [*
        [ 0, 1 ]
    *]
*]
Small group ID: 9111
[* <3, 5, 2>, <0, 0>,
    [ 5 ],
    [* *]
*]
Small group ID: 9302
[* <3, 2, 1>, <4, 0>, [* *], [* *] *]
Small group ID: 9305
[* <3, 4, 1>, <2, 0>, [* *], [* *] *]
Small group ID: 9308
[* <3, 6, 1>, <0, 0>, [* *], [* *] *]
Small group ID: 9310
[* <3, 7, 0>, <7, 0>, [* *], [* *] *]
\end{code}
\end{example}

\begin{bibdiv}
\begin{biblist}

\bib{Magma}{article}{
   author={Bosma, Wieb},
   author={Cannon, John},
   author={Playoust, Catherine},
   title={The Magma algebra system. I. The user language},
   note={Computational algebra and number theory (London, 1993)},
   journal={J. Symbolic Comput.},
   volume={24},
   date={1997},
   number={3-4},
   pages={235--265},
   issn={0747-7171},
   review={\MR{1484478}},
}

\bib{BMW}{article}{
   author={Brooksbank, Peter A.},
   author={Maglione, Joshua},
   author={Wilson, James B.},
   title={A fast isomorphism test for groups whose Lie algebra has genus 2},
   journal={J. Algebra},
   volume={473},
   date={2017},
   pages={545--590},
   issn={0021-8693},
   review={\MR{3591162}},
}

\bib{BW:isometry}{article}{
   author={Brooksbank, Peter A.},
   author={Wilson, James B.},
   title={Computing isometry groups of Hermitian maps},
   journal={Trans. Amer. Math. Soc.},
   volume={364},
   date={2012},
   number={4},
   pages={1975--1996},
   issn={0002-9947},
   review={\MR{2869196}},
}

\bib{StarAlge}{misc}{
   author={Brooksbank, Peter A.},
   author={Wilson, James B.},
   title={StarAlge},
   publisher={GitHub},
   year={2019},
   %edition={version 1.2.3},
   note={\url{https://github.com/thetensor-space/StarAlge}},
}

\bib{LGM:book}{book}{
   author={Leedham-Green, C. R.},
   author={McKay, S.},
   title={The structure of groups of prime power order},
   series={London Mathematical Society Monographs. New Series},
   volume={27},
   note={Oxford Science Publications},
   publisher={Oxford University Press, Oxford},
   date={2002},
   pages={xii+334},
   isbn={0-19-853548-1},
   review={\MR{1918951}},
}

\bib{LM:semi-extraspecial}{unpublished}{
   author={Lewis, Mark L.},
   author={Maglione, Joshua},
   title={Enumerating isoclinism classes of semi-extraspecial groups},
   note={Proc. Edinb. Math. Soc. (2), to appear},
}

\bib{Sylver}{misc}{
   author={Maglione, Joshua},
   author={Wilson, James B.},
   title={Sylver},
   publisher={GitHub},
   year={2019},
   %edition={version 1.2.3},
   note={\url{https://github.com/thetensor-space/Sylver}},
}

\bib{TensorSpacePackage}{misc}{
   author={Maglione, Joshua},
   author={Wilson, James B.},
   title={TensorSpace},
   publisher={GitHub},
   year={2019},
   %edition={version ???},
   note={Contributions from Peter A. Brooksbank,
    \url{https://github.com/thetensor-space/TensorSpace}},
}

\bib{Wilson:decomposable}{article}{
   author={Wilson, James B.},
   title={Existence, algorithms, and asymptotics of direct product
   decompositions, I},
   journal={Groups Complex. Cryptol.},
   volume={4},
   date={2012},
   number={1},
   pages={33--72},
   issn={1867-1144},
   review={\MR{2921155}},
}

\end{biblist}
\end{bibdiv}

\printindex

\end{document}


\section{Individual Workload}
The workload of this assignment was divided as follows.

Davide Pedranz:
\begin{itemize}
    \item Generation of the datasets.
    \item Implementation of the basic Rosenblatt algorithm.
    \item Experiments for different number of iterations and different values of $N$.
\end{itemize}

Samuel Giacomelli:
\begin{itemize}
    \item Extension of Rosenblatt perceptron training algorithm for different values of $c$ and inhomogeneous hyperplanes.
    \item Experiments for different values of $c$ and inhomogeneous hyperplanes.
\end{itemize}

We worked together on the report:
each of us focused more about the part that he implemented, but then we improved and refined the whole report together.


\documentclass{article}
\pagestyle{empty}
\usepackage{amsmath,amssymb,amsfonts}
\usepackage{graphicx}
\usepackage{multicol}
\setlength{\oddsidemargin}{0in} \setlength{\evensidemargin}{0in}
\setlength{\topmargin}{0in} \setlength{\textheight}{8.5in}
\setlength{\textwidth}{6.5in}

\begin{document}
\begin{flushleft}
	\bfseries{MATH 260, Linear Algebra, Spring `14}\\
	\bfseries{Activity 3:  Matrices, Systems and Row Operations}\\
	\bfseries{Honor Code:} \hspace{3.5in}\bfseries{Names:}\\
\end{flushleft}
\begin{flushleft}
\vspace{.75in}
Directions:  Everyone should work on the assignment and should fill out their paper.  You are expected to make corrections based on what is presented on the board.  Homework problems are at the end.  The assignment will not be collected today, but may be collected in the future.

\vspace{0.2in}
\Large
In-Class Learning Goals:\\
\normalsize
\begin{enumerate}
\item Be able to convert from a system of equations to a (augmented) matrix, and back.
\item Be able to perform basic row operations on a matrix.
\item Be able to identify row echelon form (REF), and be able to manipulate a matrix to be in REF.
\item (Stretch Goal) Be able to identify reduced row echelon form (RREF) and manipulate a matrix to be in RREF.
\end{enumerate}
\vspace{0.1in}
\section*{Algebra Warmup}
Solve the following system of equations by elimination. Everytime you add two equations, or multiply by numbers, right out explicitly what you are adding together or multiplying by on the left.\\
$\begin{array}{rrrcr}
x+&y+&z&=&3\\
2x-&2y-&z&=&-9\\
-x+&y-&z&=&3
\end{array}
$

\vspace{2in}
Be sure and check your answers around your table.\\
\section{Turning Systems into Matrices}
Linear Algebra is a mathematical field designed to allow fast and easy solving of systems of equations, by denoting operations on the entire system succinctly. Notice it was rather messy to work with all those equations in the warmup excercise, imagine doing that for 5 variables or 15 variables and equations. There are two notations we use in Lin. Alg. to condense systems, \textit{Matrix-Vector Form} and \textit{Augmented Matrices}. Let's turn the system from the warmup into Matrix-Vector Form:
a) First, re-write the system and replace the variables with: $x = x_1$, $y=x_2$, $z=x_3$. Notice they are all still different, but now we can just refer to them as variable 1, 2, or 3. \\
We write all three together as a vector of size 3x1:$\textbf{\vec{x}}=\left[\begin{array}{c} x_1\\x_2\\x_3\end{array}\right]$\\
\vspace{0.5in}
b) Now write the coefficients (numbers by variables) from the 2nd equation as a \textit{vector} of size 1x3. Call it $\textbf{\vec{a}}$
\vspace{0.5in}
c) Multiply $\textbf{\vec{a}\cdot\vec{x}$. Does it look familiar? Discuss at your table some. \\
\vspace{1in}
d) Now make a matrix of the variable's coefficients, we'll call it \textbf{A} (write it out). What would $\textbf{A}\cdot\textbf{\vec{x}}$ be? (You don't need to do the multiplication, but discuss at your table)\\
\vspace{0.5in}
e) We're almost there\cdots . Finally, right the values on the right-hand side of the ='s as a 3x1 vector. Call it $\textbf{\vec{b}}$. \\
\vspace{0.5in}
f) Using the vectors $\textbf{\vec{x}}$, $\textbf{\vec{b}}$ and matrix \textbf{A}, try writing out the system of equations from the warmup. (We'll discuss the answer as a class)\\
\vspace{0.25in}
g) Augmented Matrix form is just a subset of these, where we keep just the coefficients (\textbf{A}) and the right-hand-side (\textbf{\vec{b}}). We write
Matrices for today's problems:\\

$\textbf{A}=\left[
\begin{array}{c}
	2\\
	4\\
	-1\\
\end{array}
\right]
$
\hspace{.1in}
$\textbf{B}=\left[
\begin{array}{ccc}
3 & 2 & -5
\end{array}\right]$
\hspace{.1in}

$\textbf{C}=\left[
\begin{array}{cc}
1 & 4\\
-3 & 5
\end{array}
\right]
$
\hspace{.1in}
$\textbf{D}=\left[
\begin{array}{cc}
2 & 7x\\
x^2 & 3x^3
\end{array}
\right]$
\hspace{.1in}
$\textbf{E}=\left[
\begin{array}{ccc}
3x & 8 & 2x^2 +1\\
x & x^2+x & x^3
\end{array}
\right]
$

\section*{Warmup: Constants and Matrices}
a) \hspace{.1in} Find $k\textbf{C}$ where $k$ is a constant. What is $k\textbf{C}$ if $k=3$?\\
\vspace{1in}
b)\hspace{.1in}Show that: $k\textbf{C}+g\textbf{C}=(k+g)\textbf{C}$ where $k$ and $g$ are constants. This is a `distributive' property. \\
\vspace{1.25in}
It is also true (you don't have to prove/show this one) that if \textbf{A} and \textbf{B} are both $m\times n$ matrices then: \\
$k(\textbf{A}+\textbf{B})=k\textbf{A}+k\textbf{B}$ \\
c)\hspace{.1in}Show that: $k(g\textbf{C})=(kg)\textbf{C}$. This is an `associtivity' property. \\

\newpage
\section*{Problem 1:Vectors, and Vectors with Matrices}
\vspace{0.1in}
Notes on finding expected dimensions of multiplication:\\
\vspace{1in}
a)\hspace{.1in} Find the expected dimension of \textbf{AB}, \textbf{BA}, and \textbf{BE}\\
\vspace{1in}
b)\hspace{.1in} Now calculate each product.\\
\vspace{2.5in}
\section*{Problem 2: Matrix on Matrix}
a)\hspace{.1in} Find \textbf{CD}\\
\vspace{1in}
b) \hspace{.1in}Make a prediction: Is the statement:  $\textbf{CD} = \textbf{DC}$ true or false?\\
\textit{Feel free to discuss this at your table!}\\
\newpage
c) \hspace{.1in}Find \textbf{DC}. Were you correct?\\
\vspace{1.5in}
d) \hspace{.1in}Can you find any matrices (\textbf{A} and \textbf{B}) for which $\textbf{AB}=\textbf{BA}$? Note that here, \textbf{A} and \textbf{B} are NOT the matrices given on page 1. \textit{Hint: This is a SPECIAL circumstance}\\
\vspace{1in}
\section*{Problem 3: More Matrix on Matrix}
a) Which of these are true (give some reasoning, you don't \textit{have} to prove them):\\
$(\textbf{AB})\textbf{C}=\textbf{A}+\textbf{BC}$ \hspace{0.2in} $\textbf{A}(\textbf{B}+\textbf{C})=\textbf{AB}+\textbf{AC}$ \hspace{0.2in} $(\textbf{B}+\textbf{C})\textbf{A}=\textbf{AB}+\textbf{CA}$\\
\vspace{2in}
b) Under certain circumstances we can raise a matrix to a power. Discuss at your table what some requirements might be, and what the resultant dimensions would be.\\
\vspace{1in}
\newpage
c) Find $\textbf{CC}$.  This is equivalent to $\textbf{C}^2$. \\
\vspace{1in}
d) Find $\textbf{C}^3$. \textit{Hint: Use your result from (c) to reduce your work}\\
\vspace{1in}
e) Could you find $\textbf{D}^3$? What would it's dimensions be or if you can't find it why not?
\vspace{0.75in}

\section*{Problem 4: Transposing Matrices}
We can find what's called the `transpose' of a matrix by flipping a matrix over its ``diagonal'' . This only works for square matrices, and lets us do some nifty solving later.... specifically to find the transpose of \textbf{A}, denoted by $\textbf{A}^\texttt{T}$ for all $i,j$ $[a_{ij}]^\texttt{T}=[a_{ji}]$\\
a) Find $\textbf{C}^\texttt{T}$\\
\vspace{1in}
b) Predict how you think the transpose of \textbf{C} would change if we first multiplied by 3 (i.e. did: $(3\textbf{C})^\texttt{T}$ )\\
\vspace{1in}
\LARGE
Homework:
\normalsize
\begin{enumerate}
 \item Finish Worksheet (you may work with others on this)
\item Find: $3\textbf{X}^2 + \textbf{Y}^T$ for \textbf{X} and \textbf{Y} given below. You will turn this in next week. You MUST show intermediate calculations to get full credit.
\end{enumerate}

$\textbf{X}=\left[
\begin{array}{ccc}
1 & 4 & 0\\
-3 & 5 & 1\\
1 & 0 & -6
\end{array}
\right]
$
\hspace{0.1in}
$\textbf{Y}=\left[
\begin{array}{ccc}
0 & 1 & w\\
1 & -z & 3\\
0 & 9 & -4
\end{array}
\right]
$

\end{flushleft}
\end{document}

Spring 2014 - Schmitt/Activity Latex/Activity_2_260_matrixops.tex


\documentclass{article}
\usepackage{amsmath,amssymb}
\usepackage{bm}
\usepackage[margin=1in]{geometry}
\usepackage{graphicx}
\usepackage{hyperref}
\usepackage[latin1]{inputenc}
\usepackage{units}

% paragraph layout
\setlength{\parindent}{0pt}
\setlength{\parskip}{2ex plus 0.8ex minus 0.5ex}

% derivatives
\newcommand{\dd}[2]{\frac{d #1}{d #2}}

\newcommand{\for}[0]{\quad \text{ for } \quad}
\newcommand{\xli}[0]{x_{i-1/2}}
\newcommand{\xri}[0]{x_{i+1/2}}
\newcommand{\xlj}[0]{x_{j-1/2}}
\newcommand{\xrj}[0]{x_{j+1/2}}
\newcommand{\fli}[0]{f_{i-1/2}}
\newcommand{\fri}[0]{f_{i+1/2}}

\numberwithin{equation}{section}

% XXX: indexing conventions?

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% title page

\begin{document}

\title{Weighted essentially non-oscillatory schemes}
\author{Matthew Emmett}
\maketitle

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% introduction

\section{Introduction}

We follow C.W. Shu in ``Essentially Non-oscillatory and Weighted
Essentially Non-oscillatory Schemes for Hyperbolic Conservation Laws''
(NASA/CR-97-206253, ICASE report no. 97-65).

Weighted esstentially non-oscillatory (WENO) techniques have many
applications.  We will focus our attention on one-dimensional
hyperbolic conservation law of the form
\begin{gather}
  \label{eq:pdecons}
  q_t + \bigl( f(q) \bigr)_x = 0.
\end{gather}
Finite-volume schemes do not solve \eqref{eq:pdecons} directly.  They
solve its integrated version instead.  Integrating \eqref{eq:pdecons}
over the interval $[a,b]$ we obtain
\begin{equation*}
  \dd{}{t} \overline{q}(t)
    + \frac{1}{b - a} \Bigl( f\bigl(q(b,t)\bigr)
                                - f\bigl(q(a,t)\bigr) \Bigr) = 0
\end{equation*}
where
\begin{equation*}
  \overline{q}(t)
    \equiv \frac{1}{b - a} \int_{a}^{b} q(\xi,t) \;d\xi
\end{equation*}
is the average value of $q$ over $[a,b]$.  This leads us to one of
the central problems in implementing a numerical scheme to solve
\eqref{eq:pdecons}: obtaining the values of $q$ at the boundaries $a$
and $b$ based on the average $\overline{q}$ of $q$.  This is the
\emph{reconstruction} problem.

\newpage
\section{Grid}

We consider a grid over the interval $[a,b]$ with $N$ cells.  We
denote the $N+1$ cell boundaries by
\begin{equation}
  x_{i-1/2} \for i = 1,\ldots,N+1
\end{equation}
so that
\begin{equation}
  a = x_{1/2} < x_{3/2} < \cdots < x_{N-1/2} < x_{N+1/2} = b.
\end{equation}
Subsequently, we denote the $N$ cells by
\begin{equation}
  C_i = [\xli, \xri] \for i=1,\ldots,N;
\end{equation}
the $N$ cell centres by
\begin{equation}
  x_i = \frac{\xli + \xri}{2} \for i=1,\ldots,N;
\end{equation}
the $N$ cell sizes by
\begin{equation}
  \Delta x_i = \xri - \xli \for i=1,\ldots,N;
\end{equation}
and the maximum cell size by
\begin{equation}
  \Delta x = \max_{i=1,\ldots,N} \Delta x_i.
\end{equation}

We denote the contiguous stencil around the cell $C_i$, containing $k$
cells shifted to the left by $r$ cells, by
\begin{equation}
  S_i^{r,k} = C_{i-r} \cup \cdots \cup C_{i-r+k-1}.
\end{equation}
Note that $S_i^{r,k}$ spans $k$ cells and contains $k+1$ cell
boundaries.

\newpage
\section{One dimensional reconstruction for smooth functions}
\label{sec:reconstruction}

Given the cell averages $\overline{f}_j$ of a function $f$ where
\begin{equation}
  \overline{f}_j = \frac{1}{\Delta x_j} \int_{\xlj}^{\xrj} f(\xi) \;d\xi
\end{equation}
we wish to find approximations to the function $f$ at various points
within each cell.  In particular, we might be interested in
approximating the function at the left cell boundary $\xli$, the right
cell boundary $\xri$, or at any point $\xi$ within the cell $C_i$.  If
the approximations are computed using $k$ cell averages, they should
be $k$-order accruate.  The remainder of this section will be devoted
to finding these approximations and showing that they are $k$-order
accuarate.  As it turns out, we will show that there are constants
$c_j$ (hereafter called \emph{reconstruction coefficients}) such that
the reconstructed values are given by
\begin{equation*}
  f(\xi) \approx \sum_{j=0}^{k-1} c_j\; \overline{f}_{i-r+j}.
\end{equation*}
That is, given a stencil $S_i^{r,k}$ that spans the $k$ cells
$C_{i-r},\ldots,C_{i-r+k-1}$, the reconstructed value of the original
function at some point $\xi$ in $C_i$ can be obtained using the cell
averages $\overline{f}_{j}$ over the cells $C_j$ in the stencil
$S_i^{r,k}$.  In general, the reconstruction coefficients $c_j$ depend
on the reconstruction point $\xi$, order $k$, left shift $r$, and cell
$C_i$, but \emph{not} on the function $f$.

In order to obtain the reconstruction coefficients $c_j$ and prove
accuracy, we will find polynomials $p^r_i$ of degree at most $k-1$
such that each $p^r_i$ is a $k$-order accurate approximation to $f$
inside $C_i$.  That is, given the cell averages $\overline{f}_j$, we
will find polynomials $p^r_i$ such that
\begin{equation*}
  p^r_i(x) = f(x) + O(\Delta x^k) \for x \in C_i.
\end{equation*}

In order to find these polynomials, we consider the function
\begin{equation}
  \label{eq:V}
  V(x) = \int_a^x f(\xi) \;d\xi.
\end{equation}
Using the cell averages $\overline{f}_j$ we can compute $V$ at the
cell boundaries $\xri$ through
\begin{align}
  V(\xri) &= \int_a^{\xri} f(\xi) \;d\xi \nonumber \\
          &= \sum_{j=1}^i \int_{\xlj}^{\xrj} f(\xi) \;d\xi \nonumber \\
          &= \sum_{j=1}^i \overline{f}_j \Delta x_j.
          \label{eq:Vsum}
\end{align}

Focusing on a particular cell $C_i$ and stencil $S_i^{r,k}$, the
unique polynomial $P^r_i$ of order $k$ which interpolates $V$ at the
$k+1$ points
\begin{equation*}
  x_{i-r-1/2}, \ldots, x_{i-r+k-1/2}
\end{equation*}
is given by
\begin{equation}
  \label{eq:P}
  P^r_i(x) = \sum_{l=0}^{k} \Biggl(
    V(x_{i-r+l-1/2}) \prod_{m=0, m \neq l}^{k}
      \frac{(x - x_{i-r+m-1/2})}{(x_{i-r+l-1/2} - x_{i-r+m-1/2})}
    \Biggr).
\end{equation}
This is the interpolating polynomial of $V$ in Lagrange form.
It can be shown (see Appendix~\ref{app:lagrange}) that
\begin{equation*}
  P^r_i(x) = V(x) + O(\Delta x^{k+1}) \for x \in S_i^{r,k}.
\end{equation*}
Therefore, the derivative $p^r_i$ of $P^r_i$ satisfies
\begin{equation*}
  p^r_i(x) = \dd{}{x} P^r_i(x) = f(x) + O(\Delta x^k) \for x \in S_i^{r,k}
\end{equation*}
and $p^r_i$ is of order $k-1$.

Furthermore, the cell averages of $p^r_i$ over the cells $C_j$ that
comprise the stencil $S_i^{r,k}$ satisfy
\begin{align*}
  \frac{1}{\Delta x_j} \int_{\xlj}^{\xrj} p^r_i(\xi) \;d\xi
    &= \frac{1}{\Delta x_j} \int_{\xlj}^{\xrj} P'_i(\xi) \;d\xi \\
    &= \frac{1}{\Delta x_j} \biggl( P^r_i(\xrj) - P^r_i(\xlj) \biggr) \\
    &= \frac{1}{\Delta x_j} \biggl( V(\xrj) - V(\xlj) \biggr) \\
    &= \frac{1}{\Delta x_j} \biggl( \int_a^{\xrj} f(\xi) \;d\xi
      - \int_a^{\xlj} f(\xi) \;d\xi \biggr) \\
    &= \frac{1}{\Delta x_j} \biggl(
      \int_{\xlj}^{\xrj} f(\xi) \;d\xi \biggr) \\
    &= \overline{f}_j \for j=i-r,\ldots,i-r+k-1.
\end{align*}
That is, the cell averages of the approximating polynomials $p^r_i$
match the cell averages the original function in each of the cells
$C_j$ which comprise the stencil $S_i^{r,k}$.

So far we have constructed polynomials $p^r_i$ that approximate the
original function $f$ on the stencils $S_{i}^{r,k}$ to $k$-order using
only the cell averages $\overline{f}_j$ for $j=i-r,\ldots,i-r+k-1$.

Now we consider the practical problem of finding the constants $c_j$.
Subtracting $V(x_{i-r-1/2})$ from $P^r_i(x)$ and using
\begin{equation*}
  \sum_{l=0}^{k} \prod_{m=0, m \neq l}^{k}
    \frac{(x - x_{i-r+m-1/2})}{(x_{i-r+l-1/2} - x_{i-r+m-1/2})} = 1
  \quad \text{ and } \quad
  V(x_{i-r+l-1/2}) - V(x_{i-r-1/2}) \equiv 0 \text{ for } l = 0
\end{equation*}
we obtain
\begin{equation*}
  P^r_i(x) - V(x_{i-r-1/2}) = \sum_{l=1}^{k} \Biggl(
    \bigl( V(x_{i-r+l-1/2}) - V(x_{i-r-1/2}) \bigr)
    \prod_{m=0, m \neq l}^{k}
      \frac{(x - x_{i-r+m-1/2})}{(x_{i-r+l-1/2} - x_{i-r+m-1/2})}
      \Biggr).
\end{equation*}
Taking the derivative of the above, we obtain
\begin{equation*}
  \dd{}{x}P^r_i(x) = \dd{}{x} \Biggl[ \sum_{l=1}^{k} \Biggl(
    \bigl( V(x_{i-r+l-1/2}) - V(x_{i-r-1/2}) \bigr) \prod_{m=0, m \neq l}^{k}
      \frac{(x - x_{i-r+m-1/2})}{(x_{i-r+l-1/2} - x_{i-r+m-1/2})}
      \Biggr) \Biggr]
\end{equation*}
and hence
\begin{equation}
  p^r_i(x) = \sum_{l=1}^{k} \Biggl(
  \bigl( V(x_{i-r+l-1/2}) - V(x_{i-r-1/2}) \bigr) \
    \frac{\sum_{m=0, m \neq l}^{k} \prod_{n=0, n \neq l,m}^{k}
      (x - x_{i-r+n-1/2})}{\prod_{m=0, m \neq l}^{k}
      (x_{i-r+l-1/2} - x_{i-r+m-1/2})} \Biggr). \label{eq:pV}
\end{equation}
Employing \eqref{eq:Vsum}, we obtain
\begin{equation}
  p^r_i(x) = \sum_{l=1}^{k} \Biggl(
  \biggl( \sum_{j=0}^{l-1} \overline{f}_{i-r+j} \Delta x_{i-r+j} \biggr)
  \frac{\sum_{m=0, m \neq l}^{k} \prod_{n=0, n \neq l,m}^{k}
    (x - x_{i-r+n-1/2})}{\prod_{m=0, m \neq l}^{k}
    (x_{i-r+l-1/2} - x_{i-r+m-1/2})} \Biggr).
\end{equation}
Rearranging, we obtain
\begin{equation*}
  p^r_i(\xri) = \sum_{j=0}^{k-1} \sum_{l=j+1}^k
  \frac{\sum_{m=0, m \neq l}^{k} \prod_{n=0, n \neq l,m}^{k}
    (x - x_{i-r+n-1/2})}{\prod_{m=0, m \neq l}^{k}
    (x_{i-r+l-1/2} - x_{i-r+m-1/2})} \ \Delta x_{i-r+j} \overline{v}_{i-r+j}.
\end{equation*}
Therefore, the reconstruction coefficients $c_j$ used to reconstruct
the function $f$ at the point $\xi$ are given by
\begin{equation}
  c_j = \sum_{l=j+1}^k \frac{\sum_{m=0, m \neq l}^{k}
    \prod_{n=0, n \neq l,m}^{k} (\xi - x_{i-r+n-1/2})}{
    \prod_{m=0, m \neq l}^{k} (x_{i-r+l-1/2} - x_{i-r+m-1/2})}
    \ \Delta x_{i-r+j}.
\end{equation}
Note that the the reconstruction coefficients $c_j$ depend on $\xi$,
$i$, $r$, and $k$.

\subsection{Further derivatives}

In order to approximate the first derivative of the original function
$f$ we consider the first derivative of $p^r_i(x)$.  We obtain
\begin{align*}
  \dd{}{x} p^r_i(x) &= \dd{}{x} \Biggl[ \sum_{l=1}^{k} \Biggl(
  \bigl( V(x_{i-r+l-1/2}) - V(x_{i-r-1/2}) \bigr) \
    \frac{\sum_{m=0, m \neq l}^{k} \prod_{n=0, n \neq l,m}^{k}
      (x - x_{i-r+n-1/2})}{\prod_{m=0, m \neq l}^{k}
      (x_{i-r+l-1/2} - x_{i-r+m-1/2})} \Biggr) \Biggr] \\
    &= \sum_{l=1}^{k} \Biggl(
    \bigl( V(x_{i-r+l-1/2}) - V(x_{i-r-1/2}) \bigr) \
    \frac{\sum_{m=0, m \neq l}^{k} \sum_{n=0, n \neq l,m}^{k} \prod_{p=0, p \neq l, m, n}
      (x - x_{i-r+p-1/2})}{\prod_{m=0, m \neq l}^{k}
      (x_{i-r+l-1/2} - x_{i-r+m-1/2})} \Biggr).
\end{align*}
Employing \eqref{eq:Vsum}, we obtain
\begin{equation*}
  \dd{}{x} p^r_i(x) = \sum_{l=1}^{k} \Biggl(
  \biggl( \sum_{j=0}^{l-1} \overline{v}_{i-r+j} \Delta x_{i-r+j} \biggr)
  \frac{\sum_{m=0, m \neq l}^{k} \sum_{n=0, n \neq l,m}^{k} \prod_{p=0, p \neq l, m, n}
    (x - x_{i-r+p-1/2})}{\prod_{m=0, m \neq l}^{k}
    (x_{i-r+l-1/2} - x_{i-r+m-1/2})} \Biggr).
\end{equation*}
Rearranging, we obtain
\begin{equation*}
  \dd{}{x} p^r_i(x) = \sum_{j=0}^{k-1} \sum_{l=j+1}^k
  \frac{\sum_{m=0, m \neq l}^{k} \sum_{n=0, n \neq l,m}^{k} \prod_{p=0, p \neq l, m, n}
    (x - x_{i-r+p-1/2})}{\prod_{m=0, m \neq l}^{k}
    (x_{i-r+l-1/2} - x_{i-r+m-1/2})}
  \ \Delta x_{i-r+j} \overline{v}_{i-r+j}.
\end{equation*}
Therefore, the reconstruction coefficients for the first derivative
are
\begin{equation*}
  c_j = \sum_{l=j+1}^k
  \frac{\sum_{m=0, m \neq l}^{k} \sum_{n=0, n \neq l,m}^{k} \prod_{p=0, p \neq l, m, n}
    (\xi - x_{i-r+p-1/2})}{\prod_{m=0, m \neq l}^{k}
    (x_{i-r+l-1/2} - x_{i-r+m-1/2})}
  \ \Delta x_{i-r+j}
\end{equation*}

\subsection{Summary}

In summary, given a stencil $S_i^{r,k}$ and the cell averages
$\overline{f}_j$ of a function $f$, we can reconstruct $f$ at any
point $\xi$ in the cell $C_i$ according to
\begin{equation}
  \label{eq:sumvri}
  f(\xi) \approx \sum_{j=0}^{k-1} c_j\; \overline{f}_{i-r+j}
\end{equation}
where
\begin{equation}
  c_j = \sum_{l=j+1}^k \frac{\sum_{m=0, m \neq l}^{k}
    \prod_{n=0, n \neq l,m}^{k} (\xi - x_{i-r+n-1/2})}{
    \prod_{m=0, m \neq l}^{k} (x_{i-r+l-1/2} - x_{i-r+m-1/2})}
  \ \Delta x_{i-r+j}.
\end{equation}
Furthermore, the approximation is accurate to order $k$ so that
\begin{equation*}
  \sum_{j=0}^{k-1} c_j\; \overline{f}_{i-r+j} = f(\xi) + O(\Delta x^k)
\end{equation*}
where
\begin{equation*}
  \Delta x = \max_{j=i-r,\ldots,i-r+k-1} \Delta x_j.
\end{equation*}
The permissable values of left shift parameter $r$ in
\eqref{eq:sumvri} are $-1,\ldots,k-1$ so that the results of
Appendix~\ref{app:lagrange} hold.

\newpage
\section{One dimensional reconstruction for piece-wise smooth functions}

The solutions of hyperbolic conservation laws may contain
discontinuities, and therefore we are interested in reconstructing
piecewise smooth functions.  A piecewise smooth function $f$ is smooth
except at finitely many isolated points.  At these points, $f$ and its
derivatives (at least up to the order of the scheme) are assumed to
have finite left and right limits.

For such piecewise smooth functions, the order of accuracy herein
referred to is formal.  That is, it is defined as the accuracy
determined by the local error in the smooth regions of the function.

The basic idea of WENO is to use a convex combination of several
stencils to form the reconstruction of $f$, and, if a stencil contains
a discontinuity, its weight should be close to zero.  In smooth
regions, using several stencils will also serve to increase the order
of accuracy.

Consider the $k$ stencils
\begin{equation*}
  S_i^{r,k} \for r=0,\ldots,k-1
\end{equation*}
that can be used to reconstruct the value of $f$ at some point $\xi$
in the cell $C_i$.  These stencils span $2k-1$ cells.  We denote the
$k$ different reconstructions by
\begin{equation}
  \label{eq:fr}
  f(\xi) \approx f^r = \sum_{j=0}^{k-1}\; c^r_j \bar{v}_{i-r+j} \for r=0,\dots,k-1
\end{equation}
where we have added the superscript $r$ to the function $f$ and the
reconstruction coefficients $c_j$ to make their dependance on the left
shift $r$ explicit.

A WENO reconstruction takes a convex combination of all $f^r$ defined
in \eqref{eq:fr} as a new approximation according to
\begin{equation}
  \label{eq:fweno}
  f(\xi) \approx \sum_{r=0}^{k-1} \omega_i^r f^r
\end{equation}
where we require
\begin{equation}
  \omega_i^r \geq 0 \quad \text{ and } \quad \sum_{r=0}^{k-1} \omega_i^r = 1.
\end{equation}

In smooth regions where all $k$ stencils that can be used to
reconstruct $f(\xi)$ in \eqref{eq:fr} do not contain discontinuities,
we could reconstruct $f(\xi)$ to order $2k-1$ using the stencil
$S_i^{k-1,2k-1}$ to obtain
\begin{equation}
  \label{eq:fopt}
  f(\xi) = \sum_{j=0}^{2k-2} c_j^*\, \bar{f}_{i-(k-1)+j}
\end{equation}
where we have added the superscript $*$ to the reconstruction
coefficients $c_j$ to highlight that they are optimal (ie, higher
order).  Combining \eqref{eq:fr}, \eqref{eq:fweno}, and
\eqref{eq:fopt}, we obtain
\begin{equation}
  \label{eq:fopt2}
  \sum_{j=0}^{2k-2} c_j^*\, \bar{f}_{i-(k-1)+j}
    = \sum_{r=0}^{k-1} \omega_i^r \left( \sum_{l=0}^{k-1} c_l^r\, \bar{f}_{i-r+l} \right).
\end{equation}
Rearranging, we obtain
\begin{equation*}
  \sum_{j=0}^{2k-2} c_j^*\, \bar{f}_{i-(k-1)+j}
    = \sum_{j=0}^{2k-2} \left(
      \sum_{l=\max(0,j-k+1)}^{\min(k-1,j)} \omega_i^{k-(j+1)+l} c_l^{k-(j+1)+l}
    \right) \bar{f}_{i-(k-1)+j}.
\end{equation*}
\newpage
Therefore, we have $2k-1$ equations
\begin{gather}
  \label{eq:omegasys}
  \sum_{l=\max(0,j-k+1)}^{\min(k-1,j)} \omega_i^{k-(j+1)+l} c_l^{k-(j+1)+l} = c_j^*
    \for j = 0,\ldots,2k-2
\end{gather}
at each $i$ (and $\xi$) for the weights $\omega_i^r$.  For
unstructured grids the systems \eqref{eq:omegasys} are
over-determined, and therefore we must use some kind of optimisation
algorithm in order to find the weights $\omega_i^r$.  For structured
grids the systems \eqref{eq:omegasys} are no longer over-determined,
and the weights $\omega_i^r$ can be found explicity (and are
independent of $i$).

The weights $\omega_i^r$ defined by \eqref{eq:fopt2} and determined by
\eqref{eq:omegasys} are called \emph{optimal weights} since they can
be used to reconstruct a function to order $2k-1$ in regions where the
function is smooth.  We will henceforth denote the optimal weights by
$\varpi_i^r$.

We now consider the practical problem of choosing the weights
$\omega_i^r$.  If we choose the weights $\omega_i^r$ sufficiently
close to the optimal weights $\varpi_i^r$ in regions where the
function is smooth, then we can achieve $2k-1$ order accuracy.  In
order to determine how close to the optimal weights $\varpi_i^r$ the
weights $\omega_i^r$ must be choosen we consider the reconstruction
\begin{equation}
  \label{eq:omegacloseeqn}
  f(\xi) \approx \sum_{r=0}^{k-1} \omega_i^r f^r
    = \sum_{r=0}^{k-1} \varpi_i^r f^r
    + \sum_{r=0}^{k-1} \bigl( \omega_i^r - \varpi_i^r \bigr) f^r.
\end{equation}
If we choose
\begin{equation}
  \label{eq:omegaclose}
  \omega_i^r = \varpi_i^r + O(\Delta x^{k-1})
\end{equation}
then each term in the last summation of \eqref{eq:omegaclose} becomes
$O(\Delta x^{2k-1})$ and therefore $2k-1$ order accuracy is preserved
by the reconstruction.

If we define
\begin{equation}
  \label{eq:omega}
  \omega_i^r = \frac{\alpha_i^r}{\alpha_i^0 + \cdots + \alpha_i^{k-1}}
\end{equation}
where
\begin{equation}
  \label{eq:alpha}
  \alpha_i^r = \frac{\varpi_i^r}{(\epsilon + \sigma_i^r)^p} \for r = 0, \ldots, k-1;
\end{equation}
and $\epsilon$ is a positive real number used to avoid dividing by
zero (usually $\epsilon = 10^{-6}$), $p$ is some power (usually 2),
and $\sigma_i^r$ is a measure of the smoothness of the function $v$ in
the stencil $S^{r,k}_i$; with the smoothnesses $\sigma_i^r$ chosen
appropriately, then \eqref{eq:omegaclose} is satisfied.

Typically, the smoothness measurement presented by Jiang and Shu is
used.  They define the smoothness according to
\begin{equation}
  \label{eq:sigma}
  \sigma_i^r = \sum_{l=1}^{k-1} \int_{\xlj}^{\xrj} (\Delta x_j)^{2l-1} \left( \frac{d^l}{dx^l} p_i^r(x)  \right)^2 \;dx
\end{equation}
which is the sum of the $L^2$ norms of the derivatives of the
approximating polynomial.

\newpage
\subsection{One-sided (up/down wind) reconstructions}

In some situations we may need to impose that some cells be excluded
from the reconstruction process.  For example, at the front of a
dam-break flow with a positive front velocity there is a wet-dry
interface and the dry cells to the right of the front should be
avoided.

A \emph{left-biased} WENO reconstruction is one in which the weights
\begin{equation*}
  \omega_i^r=0 \quad \text{ for } \quad r < s
\end{equation*}
where $s>0$ is some parameter that controls how many cells are
excluded from the reconstruction \eqref{eq:fweno}.  Intuitively, $s$
is also the number of cells to exlude from the right.

A \emph{right-biased} WENO reconstruction is one in which the weights
\begin{equation*}
  \omega_i^r=0 \quad \text{ for } \quad r > k - |s| - 1
\end{equation*}
where $s<0$ is some parameter that controls how many cells are
excluded from the reconstruction \eqref{eq:fweno}.  Intuitively, $|s|$
is also the number of cell to exclude from the left.

That is, if $s > 0$ the WENO reconstruction will be left-biased and
reconstructions with $r < s$ will be ignored; if $s<0$ the WENO
reconstruction will be right-biased and reconstructions with $r > k -
|s| - 1$ will be ignored.  Once again, we need to determine optimal
weights for both left- and right-biased reconstructions.

For left-biased reconstructions ($s > 0$), we reconstruct $f(\xi)$ to
order $2k - s - 1$ using the stencil $S_i^{k-1,\; 2k-s-1}$ to obtain the
optimal reconstruction coefficients $c^*_j$ (similar to
\eqref{eq:fopt}).  Therefore, similar to \eqref{eq:omegasys}, we have
$2k-s-1$ equations
\begin{equation}
  \label{eq:left_omegasys}
  \sum_{l=\max(0,j-k+s+1)}^{\min(k-1,j)} \omega_i^{k-(j+1)+l} c_l^{k-(j+1)+l} = c_j^*
    \for j = 0,\ldots,2k-s-2.
\end{equation}

For right-biased reconstructions ($s < 0$), we reconstruct $f(\xi)$ to
order $2k - |s| - 1$ using the stencil $S_i^{k-|s|-1,\; 2k-|s|-1}$ to obtain the
optimal reconstruction coefficients $c^*_j$ (similar to
\eqref{eq:fopt}).  Therefore, similar to \eqref{eq:omegasys}, we have
$2k-|s|-1$ equations
\begin{equation}
  \label{eq:right_omegasys}
  \sum_{l=\max(0,j-k+|s|+1)}^{\min(k-1,j)} \omega_i^{k-(j+1)+l} c_l^{k+s-(j+1)+l} = c_j^*
    \for j = 0,\ldots,2k-|s|-2.
\end{equation}

%%
%% appendix
%%

\newpage
\appendix
\section{Error of Lagrange interpolating polynomials}
\label{app:lagrange}

Let $f(x) \in C^{n}([a,b])$, and $p(x)$ be the interpolating
polynomial of degree $n-1$ such that
\begin{equation}
  p(x_i) = f(x_i) \for i=1,\ldots,n
\end{equation}
where
\begin{equation}
  a = x_1 < x_2 < \cdots < x_{n-1} < x_n = b.
\end{equation}
Then
\begin{equation}
  p(x) = f(x) + O(\Delta x^n) \for x \in [a,b]
\end{equation}
where
\begin{equation}
  \Delta x = \max_{i=2,\ldots,n} x_i - x_{i-1}.
\end{equation}

\textbf{Proof.}  Let $x \in [a,b]$.  If $x = x_i$ for some
$i=1,\ldots,n$ then $f(x) - p(x) = 0$ since $p(x)$ is the
interpolating polynomial.  Otherwise, let
\begin{equation}
  \Phi(x) = \frac{f(x) - p(x)}{\prod_{i=1}^n (x - x_i)}
\end{equation}
and
\begin{equation}
  g(x,\xi) = f(\xi) - p(\xi) - \Phi(x) \prod_{i=1}^n (\xi - x_i).
\end{equation}
Then $g(x,\xi)$ is $n$ times differentiable with respect to $\xi$,
$g(x,x_i) = 0$ for $i=1,\ldots,n$, and $g(x,x) = 0$.  Applying Rolle's
theorem successively across all interpolation points $x_i$ and $x$ we
obtain
\begin{equation}
  \label{eq:xistar}
  \frac{\partial^n}{\partial \xi^n} g(x,\xi)\biggr|_{\xi=\xi^*} = 0
\end{equation}
for some $\xi^* \in (a,b)$.  Futhermore
\begin{equation}
  \label{eq:partials}
  \frac{\partial^n}{\partial \xi^n} g(x,\xi) = f^n(\xi) - n!\;\Phi(x)
\end{equation}
so that, combininig \eqref{eq:xistar} and \eqref{eq:partials}, we obtain
\begin{equation}
  \Phi(x) = \frac{f^n(\xi^*)}{n!}
\end{equation}
and therefore
\begin{equation}
  f(x) - p(x) = \frac{f^n(\xi^*)}{n!} \prod_{i=1}^n (x - x_i).
\end{equation}
Finally, we conclude that
\begin{equation}
  p(x) = f(x) + O(\Delta x^n).
\end{equation}
That is, if $p(x)$ interpolates $f(x)$ at $n$ points, then it is
accurate to $O(\Delta x^n)$ where $\Delta x$ is the maximum space
between the interpolating points.

\end{document}


\subsection{Implemented Analyses}

The detectable error types are highly dependent on the input analyses, given that if an analysis for an error type is not implemented and dynamically loaded when running the Analysis Engine, the error will not be detected. At the time of writing, only analyses described in this section have been implemented for the described error types.

\subsubsection{Liveness Analysis}
Liveness analysis has been implemented over the given input program, utilizing the powerset of the set of variables in the input program for the analysis.
This analysis is implemented as described by Møller and Schwartzbach in \cite{spa}, using set unions and set intersections for keeping track of liveness and a rule for assignment modeling the fact that \textit{"... the set of live variables before the assignment is the same as the set after the assignment, except for the variable being written to and the variables that are needed to evaluate the right-hand-side expression."}.

\newpar Møller and Schwartzbach define the auxilary definition $JOIN(v)$, seen below.

\begin{equation*}
    J O I N (v) = \mathop{{\bigcup}}_{w \in succ(v)} [[w]]
\end{equation*}

\noindent This is implemented in the analysis as a union on the successors of a node and the state for the node, $w$, in the \texttt{join\_lub} function, seen below.

\begin{minted}{python}
def join_lub(analysis, cfgn):
    club = frozenset()
    for n in cfgn.succ:
        club = analysis.least_upper_bound(club, analysis.state[n])
    return club
\end{minted}

\noindent \texttt{least\_upper\_bound} is defined on \texttt{Analysis} as a union on two sets, making the code equivalent to the auxilary definition.

\begin{minted}{python}
def least_upper_bound(self, left, right):
    return left.union(right)
\end{minted}

\noindent The assignment rule is defined by Møller and Schwartzbach as

\begin{equation*}
    (X=E: [[v]] = J O I N(v) \backslash\{X\} \cup \operatorname{vars}(E))
\end{equation*}

\noindent This in turn is implemented as the rule \texttt{assign}, seen below, matching the aforementioned rule.

\begin{minted}{python}
def assign(analysis,cfgn):
    jvars = (join_lub(analysis,cfgn)).difference(frozenset([cfgn.lval]))
    return analysis.least_upper_bound(jvars,cfgn.rval.vars_in)
\end{minted}

\subsubsection{Available Expressions}
As stated by Møller and Schwartzbach in \cite{spa}, an \textit{"expression in a program is available at a program point if its current value has already been computed earlier in the execution"}, and this information can be used for program optimization. Similar to liveness analysis, a lattice of all available expressions for all program points is used to find a lattice for analysis. Again, similar to liveness analysis, the available expressions are tracked using sets intersections and unions, as described by Møller and Schwartzbach.

\newpar Møller and Schwartzbach define the auxilary definition $JOIN(v)$, seen below.

\begin{equation*}
    J O I N (v) = \mathop{\bigcap}_{w \in \operatorname{pred}(v)} [[w]]
\end{equation*}

\noindent This is implemented in the analysis as the intersection of the predecessors of a node and the state for the node, $w$, in the \texttt{join\_glb} function, seen below.

\begin{minted}{python}
def join_glb(analysis, cfgn):
    if len(cfgn.pred) == 0:
        return frozenset()
    cglb = analysis.state[cfgn.pred[0]]
    for n in cfgn.pred:
        cglb = analysis.greatest_lower_bound(cglb, analysis.state[n])
    return cglb
\end{minted}

\noindent \texttt{greatest\_lower\_bound} is defined on \texttt{Analysis} as the intersection of two sets, making the code equivalent to the auxilary definition.

\begin{minted}{python}
def greatest_lower_bound(self, left, right):
    return left.intersection(right)
\end{minted}

\noindent The assignment rule is defined by Møller and Schwartzbach as

\begin{equation*}
    [v]=(J O I N(v) \cup \operatorname{exps}(E)) \downarrow X
\end{equation*}

\noindent This in turn is implemented as the rule \texttt{assign}, seen below, matching the aforementioned rule.

\begin{minted}{python}
def assign(analysis, cfgn):
    jexprs = join_glb(analysis, cfgn)
    tset = analysis.least_upper_bound(jexprs, cfgn.rval.sub_exprs())
    fset = frozenset()
    for x in tset:
        if not x.var_in(cfgn.lval):
            fset = fset.union(frozenset([x]))
    return fset
\end{minted}

\subsubsection{Busy Expressions}
As stated by Møller and Schwartzbach in \cite{spa}, an \textit{"expression is very busy if it will definitely be evaluated again before its value changes"}, and can again be used for program optimization by reordering a given computation to the earliest point in time in order to optimize execution, e.g. by moving a computation outside of a loop and therefore only perform the computation once. This analysis is similar to the analysis of available expressions, since it operates over the same lattice structure and tracks busy expressions using sets.

\newpar Møller and Schwartzbach define the auxilary definition $JOIN(v)$, seen below.

\begin{equation*}
    J O I N (v) = \mathop{\bigcap}_{w \in \operatorname{succ}(v)} [[w]]
\end{equation*}

\noindent This is implemented in the analysis as the intersection of the predecessors of a node and the state for the node, $w$, in the \texttt{join\_glb} function, seen below.

\begin{minted}{python}
def join_glb(analysis, cfgn):
    if len(cfgn.succ) == 0:
        return frozenset()
    cglb = analysis.state[cfgn.succ[0]]
    for n in cfgn.succ:
        cglb = analysis.greatest_lower_bound(cglb,analysis.state[n])
    return cglb
\end{minted}

\noindent \texttt{greatest\_lower\_bound} is, as mentioned previously, defined on \texttt{Analysis} as the intersection of two sets, making the code equivalent to the auxilary definition.

\begin{minted}{python}
def greatest_lower_bound(self, left, right):
    return left.intersection(right)
\end{minted}

\noindent The assignment rule is defined by Møller and Schwartzbach as

\begin{equation*}
    [v]=J O I N(v) \downarrow X \cup \operatorname{exps}(E)
\end{equation*}

\noindent This in turn is implemented as the rule \texttt{assign}, seen below, matching the aforementioned rule.

\begin{minted}{python}
def assign(analysis, cfgn):
    jexprs = join_glb(analysis, cfgn)
    tset = analysis.least_upper_bound(jexprs, cfgn.rval.sub_exprs())
    fset = frozenset()
    for x in tset:
        if not x.var_in(cfgn.lval):
            fset = fset.union(frozenset([x]))
    return fset
\end{minted}