\chapter{Inversion Drivers}\label{chapter:ref:Drivers}

Our task in the inversion\index{inversion} is to find the geological structure within a given three-dimensional region $\Omega$ from given geophysical
observations\index{observation}.
The structure is described by a \emph{level set function} $m$\index{level set function}.
This function can be a scalar function or may have several components,
see Chapter~\ref{Chp:ref:regularization} for more details.
Its values are dimensionless and should be between zero and one.
However, the latter condition is not enforced.
Through a mapping (see Chapter~\ref{Chp:ref:mapping}\index{mapping}) the values
of the level set function are mapped onto physical parameter $p^f$\index{physical parameter}.
The physical parameter feeds into one or more forward models\index{forward model}
which return a prediction for the observations, see Chapter~\ref{Chp:ref:forward models}.
An inversion may consider several forward models at once which we call
\emph{joint inversion}\index{joint inversion}.

The level set function describing the actual geological structure is given as
the function which minimizes a particular \emph{cost function}
$J$\index{cost function}.
This cost function is a composition of the difference of the predicted
observations to the actual observations for the relevant forward models, and
the regularization term\index{regularization} which controls the smoothness of
the level set function.
In general the cost function $J$ takes the form
\begin{equation}\label{REF:EQU:INTRO 1}
J(m) = J^{reg}(m) + \sum_{f} \mu^{data}_{f} \cdot J^{f}(p^f)
\end{equation}
where $J^{f}(p)$ is a measure of the defect of the observations predicted for
the parameter $p^f$ against the observations for forward model $f$, and
$J^{reg}(m)$ is the regularization term.
The weighting factors $\mu^{data}_{f}$ are dimensionless, non-negative
trade-off factors\index{trade-off factor}.
Potentially, values for the trade-off factors are altered during the inversion
process in order to improve the balance between the regularization term and
the data defect terms\footnote{The current version does not support an automated selection
of trade-off factors}.
The physical parameter $p^f$ depends on the level set function
$m$ in a known form:
\begin{equation}\label{REF:EQU:INTRO 1b}
p^f = M_{f}(m)
\end{equation}
where $M_f$ is a given mapping. For the case of gravity inversion
the $M_f$ is a simple linear function mapping the level set function $m$ with dimensionless values
to physical density anomaly values $\rho$.
(see Chapter~\ref{Chp:ref:mapping}\index{mapping}). In its simplest from the mapping is given as
$\rho = \rho_0 \cdot m$ where $\rho_0$ is a reference density. It is pointed out that
the inversion techniques applied do not constrain limits to the values of the level set function
although there is the notion that its values are between zero and one. However,
limits can be enforced to physical parameters using appropriate mappings.

The level set function $m$ and consequently the physical parameters $p^f$ are
defined over a three dimensional domain $\Omega$ which represented by an \escript
\class{Domain} object, see \cite{ESCRIPT}. The domain builder methods provide
functions to build appropriate domains from field data sets, see Section~\ref{Chp:ref:domain builder}.
In general the domain is a rectangular three-dimensional domain where the third dimension $x_2=z$ represents
depth. The $z=0$ surface defines the surface of the earth where $z<0$ is defining the subsurface region and
$z>0$ is defining the region above the surface, see Figure~\ref{fig:cartesianDomain}. In general physical parameters such as
density and susceptibility anomaly are known above the surface, typically assumed to be zero.
For subregions where a physical parameter is known it is assumed that the corresponding level set function as
the value zero. If required, non-zero values for the physical parameters can be set using appropriate mapping.

\begin{figure}[ht]
    \centering\includegraphics{classdep}
    \caption{Class dependencies}
    \label{fig:classes}
\end{figure}

\section{Class Dependencies}
For simplification of usage \downunder provides predefined classes that drive inversion for particular
problems. The usage of this classes is being discussed in Part~\ref{part1}. More details are shown in
Section~\ref{chapter:ref:Drivers:Drivers}. It is the role of the driver class to orchestration an
inversion. New inversions can easily be implemented by modifying the available drivers.

As illustrated in Figure~\ref{fig:classes} the driver class uses geophysical data as
managed through the \class{DataSource} class (see Chapter~\ref{Chp:ref:data sources}) and
an \escript domain to define an appropriate
costs function to be minimized. The driver class also run the minimization solver.
The \escript domain~\cite{ESCRIPT} is created using the \class{DomainBuilder}, see Chapter~\ref{Chp:ref:domain builder},
which builds an appropriate domain and mesh based on the geophysical data used in the inversion.
\class{ReferenceSystem} defines the coordinate system to be used.
Based on the inversion to be performed (gravity, magnetic, joint) the
driver class builds an appropriate cost function $J$ including the regularization term $J^{reg}$, see
\class{Regularization} class in Chapter~\ref{Chp:ref:regularization},
the forward models, see Chapter~\ref{Chp:ref:forward models} and
the required mappings, see \class{Mapping} class in Chapter~\ref{Chp:ref:mapping},
to connect the level set function with physical parameters. Finally the driver class calls the
solver to minimize the cost function, see Chapter~\ref{chapter:ref:Minimization}.

The driver classes cover commonly used cases for the convenience of users. In fact,
more general cases can be implemented in an easy way. Script \examplefile{nodriver.py} is an example
on how to implement an inversion without using one of the driver classes.

\input{Drivers}


\chapter*{Introduction}   \addcontentsline{toc}{chapter}{Introduction} \label{intro}

The tessellation of surfaces and solids into complexes of small elements such as triangles, quadrilaterals, tetrahedra or hexahedra is one of the major ingredients for many computational algorithms.
Applications range from rendering, most notably in computer games, to computational science, in particular for the numerical solution of partial differential equations on complex meshes for the study of physical phenomena.
These various areas lead to a broad range of different requirements for a mesh library, which certainly cannot be fulfilled by a single, predetermined data structure.
{\ViennaGrid} employs a highly configurable internal representation of meshes, while providing a uniform interface for the storage and access of data on mesh elements as well as STL-compatible iteration over such elements.

As an example, consider the basic building block of triangular meshes, the triangle:
The three vertices fully define the shape of the triangle, the edges can be derived from vertices if a common reference orientation of the triangles is provided.
Depending on the underlying algorithm, edges of the triangle may or may not be of interest:
\begin{itemize}
 \item Consider a class \lstinline|triangle|, holding the three vertices only.
       A triangular mesh is then some array or list of \lstinline|triangle|s and an algorithm \texttt{algo1} working only on vertices on a per-cell basis can be executed efficiently.
       An example for such an algorithm is the assembly of a linear, nodal finite element method.

 \item An \texttt{algo2} may need to have global edge information available, i.e.~only one instance of an interfacing edge of two triangles should exist in an explicit manner.
       Thus, storing the edges globally in the mesh will allow the use of \texttt{algo2}, but will at the same time introduce unnecessary edge information for \texttt{algo1}.
       Finite volume schemes can be seen as an example for this second type of algorithms.

 \item A third algorithm \texttt{algo3} may need global edge information, as well as information about the local orientation of edges with respect to each triangular cell.
      In such a case it may be preferred to additionally store mappings from global orientations to local orientations of the edges on each triangle if fast execution is desired.
      Such an additional storage of orientations will render the data structure well suited for \texttt{algo3}, but less suited for \texttt{algo1} and \texttt{algo2}.
      An example for such a third type of algorithm are -- at least to some extent -- high-order finite element methods.
\end{itemize}
The situation for tetrahedral meshes is even more complicated, because additional orientation issues of shared facets come into play.

\begin{figure}[bt]
 \centering
\mbox{
\subfigure[Store only vertices globally, do not store edges.]{
 \includegraphics[scale=0.9]{figures/storage-vglob-cglob}
\label{subfig:storage-vglob-cglob}
} \hspace{0.5cm}
\subfigure[Store vertices and edges globally.]{
 \includegraphics[scale=0.9]{figures/storage-vglob-eglob-cglob}
\label{subfig:storage-vglob-eglob-cglob}
} }
 \caption{Two storage schemes for a triangle and the underlying triangular mesh data structure.}
 \label{fig:storage-schemes-triangle}
\end{figure}

The aim of {\ViennaGrid} is to be highly customizable such that all three algorithms outlined above can be supported with an optimal data layout.
In particular, {\ViennaGrid} allows for a user-specification of the storage of elements, in particular which boundary elements are stored inside the mesh as well as which topological information is stored on each element.
After a brief introduction into the nomenclature used in this manual in Chapter \ref{chap:entities}, the configuration of the data storage layout is explained in Chapter \ref{chap:meshsetup}, and the basic steps required to fill a mesh with cells is explained in Chapter \ref{chap:meshsetup}.

In addition to high flexibility with respect to the underlying data structures, {\ViennaGrid} provides STL-compatible iterators and access to sub-elements of a mesh, cf.~Chapter \ref{chap:iterators}.
This allows for writing generic code that is a-priori independent of the underlying spatial dimension, yet enables compiler optimizations such as loop unrolling for tight loops.
In particular, a single implementation for algorithms operating in multiple dimensions and using different mesh types (triangular, hexahedral, etc.) can be obtained.

One of the strengths of {\ViennaGrid} is the generic facility provided for storing arbitrary quantities on a mesh, cf.~Chapter \ref{chap:data}.
This is achieved by the use of set of concepts which provide uniform access to data through so called accessors or fields.

A typical requirement for a meshing library is mesh refinement.
This is in particular of interest for computational science, where singularities near corners need to be resolved sufficiently well.
{\ViennaGrid} provides both uniform and adaptive refinement algorithms, cf.~Chapter \ref{chap:algorithms}, where also other geometric algorithms such as Voronoi information is covered.

Input/Output facilities are discussed in Chapter \ref{chap:io}.
Some of the library internals are discussed in Chapter \ref{chap:internals} and design decisions are outlined in Chapter \ref{chap:design}.

There are of course a number of other free software libraries having functional overlap with {\ViennaGrid}.
We give a brief discussion of the pros and cons of selected libraries in the following.
This should allow potential users of our library to get a better feeling of what to expect and what not to expect from {\ViennaGrid}.
We have carefully checked the documentation of each project, but clearly cannot guarantee that all information is fully accurate.
\begin{itemize}
  \item \textbf{CGAL} \cite{CGAL}: The focus of the Computational Geometry Algorithms Library (\texttt{CGAL}) is on geometrical algorithms such as the computation of convex hulls of point sets.
        It offers a mesh generation facility and provides iterators over cell vertices.
        However, the storage of quantities and the convenient traversal of mesh elements is not provided.

  \item \textbf{DUNE} \cite{DUNE}: \texttt{DUNE} follows a similar approach for the generic representation of meshes.
        It provides support for conforming and non-conforming grids, as well as support for parallel and distributed meshes.
        However, unlike {\ViennaGrid}, we could not find any mechanism providing a convenient means to store data on mesh elements (users are essentially required to handle their data themselves), and for the customization about the internal storage of mesh elements.

  \item \textbf{GrAL} \cite{GrAL}: The Grid Algorithms library (\texttt{GrAL}) provides mesh data structures and algorithms operating on them.
        A number of concepts used in {\ViennaGrid} such as $n$-\textit{cells} are implemented in \texttt{GrAL} as $k$-\textit{Elements}, however it does not provide any facilities to store data on mesh elements or to refine meshes.

  \item \textbf{libmesh} \cite{libmesh}: The \texttt{libmesh} library is not only a mesh library, but also a framework for numerical simulations.
        Since {\ViennaGrid} is designed to be as general as possible without tying one to a particular application prematurely, we only compare the parts in \texttt{libmesh} related to mesh handling.
        \texttt{libmesh} supports one-, two- and three-dimensional meshes and also allows to generate meshes for simple meshs.
        Iterations over elements of a mesh are carried out in a runtime manner, thus causing potential overhead.
        One of the strengths of \texttt{libmesh} is the support for mesh refinement and parallel computations.
        Support for user-defined data on mesh elements is also provided.

  \item \textbf{OpenMesh} \cite{OpenMesh}: \texttt{OpenMesh} provides a generic data structure for representing and manipulating polygonal meshes.
        The main goals are flexibility, efficiency and ease-of-use.
        Similarly to {\ViennaGrid}, generic programming paradigms are used.
        \texttt{OpenMesh} allows storing custom data of arbitrary type on mesh elements, but it seems to rely on potentially slow string comparisons at run-time to retrieve the data.
        Moreover, \texttt{OpenMesh} is specifically designed for surface (i.e.~non-volumetric) meshes, and thus only the concepts of vertices, edges and faces are used.

  \item \textbf{trimesh2} \cite{trimesh2}: \texttt{trimesh2} is a C++ library that is particularly designed for triangular meshes in 3D only.
        It explicitly targets efficiency, possibly at the expense of some generality.
        We could not find further information for a comparison with {\ViennaGrid} from the documentation provided.

  \item \textbf{VCGlib} \cite{VCGlib}: \texttt{VCGlib} processes triangular and tetrahedral meshes.
        Similar to \texttt{OpenMesh}, \texttt{VCGlib} uses the concepts of vertices, edges and faces only, so the processing of volume meshes is hampered.
        Again similar to \texttt{OpenMesh}, the provided facility to store data on mesh elements relies on potentially slow string comparisons.
\end{itemize}


\documentclass[10pt, a4paper, twoside]{basestyle}

\usepackage[backend=biber,firstinits=true,maxnames=100,style=alphabetic,maxalphanames=4,doi=true,isbn=false,url=false,eprint=true]{biblatex}
\bibliography{bibliography}

\usepackage[Mathematics]{semtex}
\usepackage{chngcntr}
\counterwithout{equation}{section}

%%%% Shorthands.

%%%% Title and authors.

\title{%
\textdisplay{%
On an Article by Celledoni et al.%
}%
}
\author{Pascal~Leroy (phl)}
\begin{document}
\maketitle
\begin{sloppypar}
\noindent
This document provides clarifications, corrections, and accuracy improvements to the formul{\ae} presented in \cite{Celledoni2007}.  It follows the notation
and conventions of that paper.  Note that the preprint \cite{Celledoni2007} differs in some of the formul{\ae} from the final publication \cite{Celledoni2008},
and that we follow the former because the latter introduced errors.
\end{sloppypar}

\section*{Preamble}
We remind the reader of the derivation formul{\ae} for the Jacobian elliptic functions (\cite{NistHMF2010}, section 22.13(i)):
\[
\begin{dcases}
\derivop{u}{\JacobiSN u} &= \JacobiCN u \JacobiDN u \\
\derivop{u}{\JacobiCN u} &= -\JacobiSN u \JacobiDN u \\
\derivop{u}{\JacobiDN u} &= -k^2 \JacobiSN u \JacobiCN u
\end{dcases}
\]
and for the hyperbolic functions (\cite{NistHMF2010}, section 4.34):
\[
\begin{dcases}
\derivop{u}{\HyperbolicTangent u} &= \HyperbolicSecant^2 u \\
\derivop{u}{\HyperbolicSecant u} &= -\HyperbolicSecant u \HyperbolicTangent u
\end{dcases}
\]

\section*{The equations of motion}
We start by writing equation (1) of \cite{Celledoni2007} in coordinates.  The coordinates of $\vm$ and $\VectorSymbol{I}$ are defined by:
\[
\vm\DefineAs
\begin{pmatrix}
m_1 \\ m_2 \\ m_3
\end{pmatrix}
\]
and:
\[
\VectorSymbol{I}\DefineAs
\begin{pmatrix}
I_1 & 0 & 0 \\ 0 & I_2 & 0 \\ 0 & 0 & I_3
\end{pmatrix}
\]
with $I_1 \leq I_2 \leq I_3$.

Euler's equation $\TimeDerivative{\vm} = \commutator{\vm}{\VectorSymbol{\gw}}$ can be written in coordinates in the principal axes frame:
\[
\TimeDerivative{\vm} =
\begin{pmatrix}
m_1 \\ m_2 \\ m_3
\end{pmatrix}
\times
\begin{pmatrix}
m_1/I_1 \\ m_2/I_2 \\ m_3/I_3
\end{pmatrix}
\]
thus:
\begin{equation}
\begin{dcases}
\TimeDerivative{m}_1 &= m_2 m_3 \pa{1/I_3 - 1/I_2}\\
\TimeDerivative{m}_2 &= m_3 m_1 \pa{1/I_1 - 1/I_3}\\
\TimeDerivative{m}_3 &= m_1 m_2 \pa{1/I_2 - 1/I_1}
\end{dcases}
\label{eqneuler}
\end{equation}
\section*{Solution of Euler's equation}
The solution of Euler's equation has three cases depending on the initial value of $\vm$ (more precisely, on the sign of
$\gD_2 = m_1^2 \frac{I_{12}}{I_1} + m_3^2 \frac{I_{32}}{I_3}$, see discussion below).  Figure~\ref{figm} illustrates the
possible evolutions of $\vm$. The sphere is the surface $\norm\vm = G$, which is an invariant of motion.  The planes are
the surfaces $\gD_2 = 0$ and separate different modes of the motion.
The blue curve is called case (i) in \cite{Celledoni2007}: $\vm$ follows a periodic curve, and when that curve is close to the $m_1$
axis we have a classical case of precession.  The red curve is case (ii), and again the motion of $\vm$ is periodic and exhibits
precession when the curve remains close to the $m_3$ axis.  The green curve is case (iii): $\vm$ takes an infinite amount
of time to reach the point $\tuple{0, G, 0}$; furthermore, the motion is unstable as any perturbation moves it either to
the blue or the red region where $\vm$ oscillates between points close to $\tuple{0, G, 0}$ and $\tuple{0, -G, 0}$; this is
the Джанибеков effect.
\begin{figure}[htb!]
\centering
\includegraphics[scale=0.45]{Celledoni-m}
\caption{Possible trajectories of $\vm$: the blue and red curves are cases (i) and (ii), respectively, and correspond to motion
with precession.  The green curve is the (unstable) case (iii) and any perturbation demonstrates the Джанибеков effect.\label{figm}}
\end{figure}

The solutions may also be visualized by intersecting the sphere $\norm\vm = 1$ with ellipsoids defined by the value of the kinetic energy $T$,
which is also a constant of motion.  Since $T = \frac{G^2 - \gD_2}{2 I_2}$, different values of $T$ determine the same modes as above.
\begin{figure}[htb!]
\centering
\includegraphics[scale=0.45]{Celledoni-G-T}
\caption{Possible trajectories of $\vm$: the sphere is identical to that of Figure~\ref{figm}.
The ellipsoids are surfaces of equal kinetic energy and intersect the sphere on the blue, red, and green curves depending on the
value of $T$ .\label{figGT}}
\end{figure}

In the rest of this section, we derive (corrected) formul{\ae} for the three cases described above.
\subsection*{Case (i)}
Case (i) of the solution of Euler's equation in section 2.2 of \cite{Celledoni2007} is:
\[
{\vm}_t =
\begin{pmatrix}
\gs B_{13} \JacobiDN\of{\gl t - \gn, k} \\
-B_{21} \JacobiSN\of{\gl t - \gn, k} \\
B_{31} \JacobiCN\of{\gl t - \gn, k}
\end{pmatrix}
\]
If we derive this expression with respect to $t$, inject in into (\ref{eqneuler}), and eliminate the elliptic functions we obtain:
\begin{equation}
\begin{dcases}
-\gs \gl k^2 B_{13} &= -B_{21} B_{31} \pa{1/I_3 - 1/I_2} \\
-\gl B_{21} &= \gs B_{13} B_{31} \pa{1/I_1 - 1/I_3} \\
-\gl B_{31} &= -\gs B_{13} B_{21} \pa{1/I_2 - 1/I_1}
\end{dcases}
\label{solneuleri}
\end{equation}
The last equation of (\ref{solneuleri}) yields the following value for $\gl$:
\begin{align*}
\gl &= \gs \frac{B_{13} B_{21}}{B_{31}} \frac{I_1 - I_2}{I_1 I_2}
= \gs\sqrt{\frac{I_1 \gD_3}{I_{13}} \frac{I_2 \gD_1}{I_{21}} \frac{I_{31}}{I_3 \gD_1}} \frac{I_1 - I_2}{I_1 I_2} \\
&= \gs\sqrt{\frac{\gD_3}{I_{21} I_1 I_2 I_3}} \pa{I_1 - I_2}
= -\gs\sqrt{\frac{\gD_3 I_{21}}{I_1 I_2 I_3}}
= -\gs \gl_3
\end{align*}
The sign change when moving $I_1 - I_2$ under the radical is necessary because $I_1 - I_2 < 0$.

It is straightforward to check that this value of $\gl$ also satisfies the other equations of (\ref{solneuleri}).  Note that it
differs in sign from the one given by \cite{Celledoni2007}: the sign error is visible in that it does not yield the proper precession
direction.

\subsection*{Case (ii)}
Case (ii) of the solution of Euler's equation in section 2.2 of \cite{Celledoni2007} is:
\[
{\vm}_t =
\begin{pmatrix}
B_{13} \JacobiCN\of{\gl t - \gn, k^{-1}} \\
-B_{23} \JacobiSN\of{\gl t - \gn, k^{-1}} \\
\gs B_{31} \JacobiDN\of{\gl t - \gn, k^{-1}}
\end{pmatrix}
\]
Just as we did above, we derive this expression with respect to $t$, inject in into (\ref{eqneuler}), and eliminate the elliptic functions:
\begin{equation}
\begin{dcases}
-\gl B_{13} &= -\gs B_{23} B_{31} \pa{1/I_3 - 1/I_2} \\
-\gl B_{23} &= \gs B_{13} B_{31} \pa{1/I_1 - 1/I_3} \\
-\gs \gl k^{-2} B_{31} &= -B_{13} B_{23} \pa{1/I_2 - 1/I_1}
\end{dcases}
\label{solneulerii}
\end{equation}
The first equation of (\ref{solneulerii}) yields the following value for $\gl$:
\begin{align*}
\gl &= \gs \frac{B_{23} B_{31}}{B_{13}} \frac{I_2 - I_3}{I_2 I_3}
= \gs\sqrt{\frac{I_2 \gD_3}{I_{23}} \frac{I_3 \gD_1}{I_{31}} \frac{I_{13}}{I_1 \gD_3}} \frac{I_2 - I_3}{I_2 I_3} \\
&= \gs\sqrt{\frac{\gD_1}{I_{23} I_1 I_2 I_3}} \pa{I_2 - I_3}
= -\gs\sqrt{\frac{\gD_1 I_{23}}{I_1 I_2 I_3}}
= -\gs \gl_1
\end{align*}
Again, note the change of sign due to the fact that $I_2 - I_3 < 0$.  And again, the same value of $\gl$ can be shown to satisfy the other
equations of (\ref{solneulerii}).

\subsection*{Case (iii)}
Case (iii) of the solution of Euler's equation in section 2.2 of \cite{Celledoni2007} is clearly incorrect as it implies that $m_1$ and $m_3$
always have the same sign, whereas it is straightforward to choose initial conditions where they do not (because the separatrix is made of two
planes, see Figure~\ref{figm}).  Instead, we introduce an extra parameter $\gs'' = ±1$ and posit a solution of the form:
\[
{\vm}_t =
\begin{pmatrix}
\gs' B_{13} \HyperbolicSecant\of{\gl t - \gn} \\
\HyperbolicTangent\of{\gl t - \gn} \\
\gs'' B_{31} \HyperbolicSecant\of{\gl t - \gn}
\end{pmatrix}
\]
Deriving this expression and injecting it into (\ref{eqneuler}) yields:
\begin{equation}
\begin{dcases}
-\gs' \gl B_{13} &= \gs'' B_{31} \pa{1/I_3 - 1/I_2} \\
\gl &= \gs' \gs'' B_{13} B_{31} \pa{1/I_1 - 1/I_3} \\
-\gs'' \gl B_{31} &= \gs' B_{13} \pa{1/I_2 - 1/I_1}
\end{dcases}
\label{solneuleriii}
\end{equation}
The second equation of (\ref{solneuleriii}) gives the following value for $\gl$:
\[
\gl = \gs' \gs'' B_{13} B_{31} \frac{I_3 - I_1}{I_1 I_3}
= \gs' \gs'' \sqrt{\frac{I_1 \gD_3}{I_{13}} \frac{I_3 \gD_1}{I_{31}}} \frac{I_3 - I_1}{I_1 I_3}
= \gs' \gs'' \sqrt{\frac{\gD_1 \gD_3}{I_1 I_3}}
\]
In this case it is a bit less obvious that the other equations yield the same value of $\gl$.  We detail the derivation for the first equation,
using the fact that ${\gs'}^2 = 1$:
\begin{align*}
\gl &= -\gs' \gs'' \frac{B_{31}}{B_{13}} \frac{I_2 - I_3}{I_2 I_3}
= -\gs' \gs'' \sqrt{\frac{I_3 \gD_1}{I_{31}} \frac{I_{13}}{I_1 \gD_3}} \frac{I_2 - I_3}{I_2 I_3} \\
&= -\gs' \gs'' \sqrt{\frac{\gD_1}{I_1 I_3 \gD_3}} \frac{I_2 - I_3}{I_2}
= \gs' \gs'' \sqrt{\frac{\gD_1}{I_1 I_3 \gD_3}} \pa{\frac{I_3}{I_2} - 1}
\end{align*}
Now note that in case (iii) we have $2 T I_2 = 1$ thus $1/I_2 = 2 T$.  $\gl$ can be rewritten as:
\[
\gl = \gs' \gs'' \sqrt{\frac{\gD_1}{I_1 I_3 \gD_3}} \pa{2 T I_3 - 1} = \gs' \gs'' \sqrt{\frac{\gD_1 \gD_3}{I_1 I_3}}
\]
where we have used the fact that $2 T I_3 - 1 = 2 T \pa{I_3 - I_2} > 0$.

We then define:
\[
\gl_2 = \sqrt{\frac{\gD_1 \gD_3}{I_1 I_3}}
\]
It is easy to see that $\gl_2$ is the common value of $\gl_1$ and $\gl_3$ in case (iii), that $\gs'$ and $\gs''$ are free parameters and that:
\[
\gl = \gs' \gs'' \gl_2
\]

\subsection*{Phase and initial value}
The phase $\gn$ and the free parameters $\gs$, $\gs'$ and $\gs''$ are determined from the initial value ${\vm}_0$ by setting $t = 0$.
\subsubsection*{Case (i)}
We have:
\[
{\vm}_0 =
\begin{pmatrix}
\gs B_{13} \JacobiDN\of{-\gn, k} \\
-B_{21} \JacobiSN\of{-\gn, k} \\
B_{31} \JacobiCN\of{-\gn, k}
\end{pmatrix}
\]
First, we set $\gs$ to be the sign of $m_{01}$.  Then, forming the quotient of the last two coordinates we find:
\[
\frac{m_{02}}{m_{03}} = \frac{B_{21}}{B_{31}}\TrigonometricTangent\of{\JacobiAmplitude\of{\gn, k}}
\]
thus:
\[
\InverseTrigonometricTangent\of{\frac{m_{02}}{m_{03}} \frac{B_{31}}{B_{21}}} = \JacobiAmplitude\of{\gn, k}
\]
and finally we obtain $\gn$ as:
\[
\gn = F\of{\InverseTrigonometricTangent\of{\frac{m_{02}}{m_{03}} \frac{B_{31}}{B_{21}}}, k}
\]

\subsubsection*{Case (ii)}
Starting from:
\[
{\vm}_0 =
\begin{pmatrix}
B_{13} \JacobiCN\of{-\gn, k^{-1}} \\
-B_{23} \JacobiSN\of{-\gn, k^{-1}} \\
\gs B_{31} \JacobiDN\of{-\gn, k^{-1}}
\end{pmatrix}
\]
we set $\gs$ to be the sign of $m_{03}$ and form the quotient of the first two coordinates.  We obtain:
\[
\frac{m_{02}}{m_{01}} = \frac{B_{23}}{B_{13}} \TrigonometricTangent\of{\JacobiAmplitude\of{\gn, k^{-1}}}
\]
and for $\gn$:
\[
\gn = F\of{\InverseTrigonometricTangent\of{\frac{m_{02}}{m_{01}} \frac{B_{13}}{B_{23}}}, k^{-1}}
\]

\subsubsection*{Case (iii)}
The initial value ${\vm}_0$  is:
\[
{\vm}_0 =
\begin{pmatrix}
\gs' B_{13} \HyperbolicSecant\of{-\gn} \\
\HyperbolicTangent\of{-\gn} \\
\gs'' B_{31} \HyperbolicSecant\of{-\gn}
\end{pmatrix}
\]
$\gs'$ and $\gs''$ are set to be the signs of $m_{01}$ and $m_{03}$, respectively.  The second coordinate immediately gives:
\[
\gn = -\InverseHyperbolicTangent\of{m_{02}}
\]

\subsection*{Implementation considerations}
Some of the formul{\ae} given by \cite{Celledoni2007} do not lend themselves to an easy implementation or lead to numerical inaccuracies.  We
describe in this section the modifications we make to these formul{\ae} in our implementation.  We also restore dimensionful formul{\ae} as needed.

\subsubsection*{The quantity $I_{jh}$}
It is simpler and more efficient to avoid absolute values, so we define:
\[
I_{jh} \DefineAs I_j - I_h
\]
This is the same quantity as in \cite{Celledoni2007} when $j \geq h$ but it has the opposite sign (it is negative) when $j < h$

\subsubsection*{The quantity $\gD_j$}
We notice that the computation of $\gD_j$ may entail cancellations, so we go back to the definition of $\norm{\vm}$ and of the kinetic energy:
\[
\begin{dcases}
G^2 &= m_1^2 + m_2^2 + m_3^2 \\
2 T &= \frac{m_1^2}{I_1} + \frac{m_2^2}{I_2} + \frac{m_3^2}{I_3}
\end{dcases}
\]
and we define a dimensionful $\gD_j$ without absolute values:
\[
\gD_j \DefineAs G^2 - 2 T I_j
\]
When, for instance, $j = 2$, this yields:
\begin{align*}
\gD_2 &= m_1^2 \pa{1 - \frac{I_2}{I_1}} + m_3^2 \pa{1 - \frac{I_2}{I_3}} \\
&= m_1^2 \frac{I_{12}}{I_1} + m_3^2 \frac{I_{32}}{I_3}
\end{align*}
and similarly:
\[
\begin{dcases}
\gD_1 &= m_2^2 \frac{I_{21}}{I_2} + m_3^2 \frac{I_{31}}{I_3} \\
\gD_3 &= m_1^2 \frac{I_{13}}{I_1} + m_2^2 \frac{I_{23}}{I_2}
\end{dcases}
\]
It is easy to see that $\gD_1$ and $\gD_3$ are the sums of terms of the same sign, so they can be computed without cancellations.  Furthermore,
$\gD_1 \geq 0$ and $\gD_3 \leq 0$.  $\gD_2$ can have either sign, which correspond exactly to cases (i) ($\gD_2 < 0$), (ii) ($\gD_2 > 0$) and
(iii) ($\gD_2 = 0$).

\subsubsection*{The elliptic modulus}
For the computation of the elliptic functions and integrals \cite{Celledoni2007} gives the value of the elliptic modulus $k$ but we need the value of
the complementary parameter $m_c = 1 - m$ (see \cite{NistHMF2010}, section 19.1.2 for an overview of the notation).  In case (i) we have:
\[
m_c = 1 - k^2 = 1 + \frac{\gD_1 I_{32}}{\gD_3 I_{21}}
\]
where we have used $\gD_3 \leq 0$.  This can be rewritten as follows:
\begin{align*}
m_c &= \frac{\gD_3 I_{21} + \gD_1 I_{32}}{\gD_3 I_{21}}
=\frac{\pa{G^2 - 2 T I_3}\pa{I_2 - I_1} + \pa{G^2 - 2 T I_1}\pa{I_3 - I_2}}{\gD_3 I_{21}} \\
&=\frac{G^2\pa{I_3 - I_1} + 2 T I_2\pa{I_1 - I_3}}{\gD_3 I_{21}}
=\frac{\gD_2 I_{31}}{\gD_3 I_{21}}
\end{align*}

Similarly, in case (ii):
\[
m_c = 1 - k^{-2} = 1 + \frac{\gD_3 I_{21}}{\gD_1 I_{32}}
=\frac{\gD_1 I_{32} + \gD_3 I_{21}}{\gD_1 I_{32}}
=\frac{\gD_2 I_{31}}{\gD_1 I_{32}}
\]
Note that in both cases we have $m_c \geq 0$.

\subsubsection*{The dimensionful equations}
$I_{jh}$ has the physical dimension of an inertial momentum $L^2 M$.  $G$ has the dimension of an angular momentum $L^2 M T^{-1} A$.  $\gD_j$ has
the same dimension as $G^2$.  $B_{jh}$ has the same dimension as $\sqrt{\gD_h}$, i.e., the same dimension as $G$.  $\gl_1$ and $\gl_3$ have the
same dimension as the quotient $\frac{G}{I_j}$, i.e., $T^{-1} A$ which is appropriate for their usage.

This analysis shows that most of the formul{\ae} in \cite{Celledoni2007} have proper physical dimensions, expect for the $1$ in the definition of
$\gD_j$ (which should be $G^2$) and for the second coordinate of $\vm$ in case (iii) which should be:
\[
m_{2t} = G \HyperbolicTangent\of{-\gn}
\]
With this adjustment we obtain the dimensionful formul{\ae}:
\begin{align*}
\gn &= -\InverseHyperbolicTangent\of{\frac{m_{02}}{G}} \\
\gl_2 &= \frac{1}{G} \sqrt{\frac{\gD_1 \gD_3}{I_1 I_3}}
\end{align*}
It is easy to verify that the argument of the $\InverseHyperbolicTangent$ is dimensionless and that $\gl_2$ has the same dimension as the quotient
$\frac{\gD_j}{G I_j}$, which has the same dimension as $\frac{G}{I_j}$, namely, $T^{-1} A$.
\printbibliography
\end{document}


\documentclass[11pt]{article}
\usepackage{cite}
\usepackage{pgf}
\usepackage{tikz}
\usepackage{amsmath,amssymb}
\usepackage{amsthm}
\usepackage{url}
\usepackage{hvorost}

\begin{document}

\title{Computing All Pure Squares in Compressed Texts}
\author{L. Khvorost\thanks{The author acknowledges support from the Federal
Education Agency of Russia, grant  2.1.1/3537.}\\
Ural State University\\
jaamal@mail.ru}
\date{}
\maketitle

\begin{abstract}
A square $xx$ is called pure if $x$ is a primitive string. We consider the problem of computing all pure squares
in a string represented by a straight-line program (SLP). An instance of the problem is an SLP $\slp{S}$ that
derives some string $S$ and we seek a solution in the form of a table that contains information about all pure
squares in $S$ in a compressed form. We present an algorithm that solves the problem in $O(|\slp{S}|^4\cdot
\log^2{|S|})$ time and requires $O(|\slp{S}|\cdot \max\{ |\slp{S}|, \log{|S|}\})$ space, where $|\slp{S}|$
(respectively $|S|$) is the size of the SLP $\slp{S}$ (respectively the length of the string $S$).
\end{abstract}

\section{Introduction}

Various compressed representations of strings are known: straight-line programs (SLPs) \cite{14,15,16,18},
collage-systems \cite{12}, string representations using antidictionaries \cite{13}, etc. Nowadays text compression
based on context-free grammars such as SLPs attracts much attention. The reason for this is not only that grammars
provide well-structured compression but also that the SLP-based compression is in a sense polynomially equivalent
to the compression achieved by the Lempel-Ziv algorithm that is widely used in practice. It means that, given a
text $S$, there is a polynomial relation between the size of an SLP that derives $S$ and the size of the
dictionary stored by the Lempel-Ziv algorithm \cite{18}.

While compressed representations save storage space, there is a price to pay: some classical problems on strings
become computationally hard when one deals with compressed data and measures algorithms' speed in terms of the
size of compressed representations. As examples we mention here the problems \textbf{Hamming distance} \cite{15} and
\textbf{Literal shuffle} \cite{4}. On the other hand, there exist problems that admit algorithms working rather well on
compressed representations: \textbf{Pattern matching} \cite{15, 10}, \textbf{Longest common substring} \cite{16},
\textbf{Computing all palindromes} \cite{16}. This dichotomy gives rise to the following research direction: to
classify important string problems by their behavior with respect to compressed data.

The \textbf{Computing All Squares} (\textbf{CAS}) problem is a well-known problem on strings. It is of importance, for
example, in molecular biology. (We just mention in passing that the story of origin and migration of mice on the
Eurasia continent was restored thanks to information on squares in DNA sequences in mouse genome \cite{19}.) It is
not yet known whether or not \textbf{CAS} admits an algorithm polynomial in the size of a compressed representation
of a given text.\footnote{A polynomial algorithm that solves \textbf{CAS} for strings represented by Lempel-Ziv
encodings was announced in~\cite{8}. This representation is slightly more general than that by SLPs. However no
details of the algorithm have ever been appeared.} In general, a string can have exponentially many squares with
respect to the size of its compressed representation. For example, the string $a^n$ has $\Theta(n^2)$ squares,
while it is easy to build an SLP of size $O(\log n)$ that derives $a^n$. So we must store information about
squares in a compressed form. Also this implies that we cannot search for squares consecutively by moving from one
square to the ``next'' one. Squares should be somehow grouped in relatively large families that are to be
discovered at once. So far we are able to overcome these difficulties for pure squares only.

A string $x$ is \emph{primitive} if $x = u^k$ for some integer $k$ implies that $k = 1$ and $u = x$. A \emph{pure}
square is a square $xx$ where $x$ is primitive. Otherwise, $xx$ is called a \emph{repetition}. We formulate the \textbf{
Computing all pure squares} problem in terms of SLPs as follows:

\problem{CAPS}{an SLP $\slp{S}$ that derives some text $S$;}{a data structure (a PS-table) that contains
information about all pure squares in $S$ in a compressed form.}

Observe that restricting to pure squares by no means makes the problem easy: the difficulties mentioned above
persist for pure squares. Indeed, the same string $a^n$ has $n-1$ pure squares, thus exponentially many with
respect to the size of its compressed representation.

Let us describe in more detail the content of the present paper and its structure. Section~2 gathers some
preliminaries about SLPs. In Section~3 we present some basic operations over SLPs widely used in paper. In
Section~4 we present two algorithms. The first algorithm, given an SLP $\slp{S}$, checks whether or not the text
$\slp{S}$ generates is square free. (A polynomial algorithm for testing square-freeness of a compressed text has been
recently developed in~\cite{new} but only for the special case of SLPs, in which the parse tree of the text is
balanced.) The second algorithm, given SLP $\slp{S}$, fills out the corresponding PS-table. Both algorithms use time
and space resources that depend polynomially on the size of $\slp{S}$ and logarithmically on the size of the text
generated by $\slp{S}$. Our algorithms closely follows the approach from~\cite{2} where an efficient solution
to \textbf{CAS} for non-compressed strings has been proposed and we reproduce the key lemmas from~\cite{2} for the reader's
convenience. Also in Section~4 we discuss functionality of PS-tables and list several problems that can be easily solved
whenever a PS-table is available. In Section~5 we summarize our results. Appendix A contains illustrative examples.

\section{Preliminaries}

We consider strings of characters from a fixed finite alphabet $\Sigma$. The \emph{length} of a string $S$ is the number
of its characters and is denoted by $|S|$. The \emph{concatenation} of strings $S_1$ and $S_2$ is denoted by $S_1 \cdot
S_2$.  A \emph{position} in a string $S$ is a point between consecutive characters. We number positions from left to
right by $1,2,\dots,|S|-1$. It is convenient to consider also the position 0 preceding the text and the position $|S|$
following it. For a string $S$ and an integer $i (0 \leq i \leq |S|)$ we define $S[i]$ as character between positions
$i$ and $i+1$ of $S$. For example $S[0]$ is a first character of $S$. A \emph{substring} of $S$ starting at a position
$\ell$  and ending at a position $r$, $0\leq \ell < r \leq |S|$, is denoted by $S[\ell \dots r]$ (in other words
$S[\ell \dots r] = S[\ell] \cdot S[\ell + 1] \cdot \mbox{\dots} \cdot S[r-1]$). We say that a substring $S[\ell \dots
r]$ \emph{touches} some position $t$ if $\ell \leq t \leq r$. The position $|x|$ of a square $xx$ is called the
\emph{center} of $xx$ and $x$ is referred to as the \emph{root} of $xx$.

A \emph{straight-line program} (SLP) $\slp{S}$ is a sequence of assignments of the form:

\begin{center}
$\slp{S}_1 = expr_1,\ \slp{S}_2 = expr_2, \dots, \slp{S}_n = expr_n,$
\end{center}
where $\slp{S}_i$ are \emph{rules} and $expr_i$ are expressions of the form:
\begin{itemize}
\item $expr_i$ is a symbol of $\Sigma$ (we call such rules \emph{terminal}), or
\item $expr_i = \slp{S}_\ell\cdot \slp{S}_r \ (\ell, r < i)$ (we call such rules \emph{nonterminal}).
\end{itemize}

Thus, an SLP is a context-free grammar in Chomsky normal form. Every SLP $\slp{S}$ generates exactly one string
$S\in\Sigma^+$ and we refer to it as the \emph{text} generated by $\slp{S}$.

{\bf Example}: The following SLP $\slp{F}_7$ generates the 7-th Fibonacci word $F_7$= \emph{a~b~a~a~b~a~b~a~a~b~a~a~b}:
\begin{center}
$\slp{F}_1 = a,\ \slp{F}_2 = b,\ \slp{F}_3 = \slp{F}_1\cdot \slp{F}_2,\ \slp{F}_4 = \slp{F}_3\cdot \slp{F}_1,$

$\slp{F}_5 = \slp{F}_4\cdot \slp{F}_3,\ \slp{F}_6 = \slp{F}_5\cdot \slp{F}_4,\ \slp{F}_7 = \slp{F}_6\cdot
\slp{F}_5$;
\end{center}

We accept the following conventions in the paper: every SLP is denoted by a capital blackboard bold letter, for
example, $\slp{S}$. Every rule of this SLP is denoted by the same letter with indices, for example,
$\slp{S}_1,\slp{S}_2,\dots$. The text that is derived from a rule is denoted by the same indexed capital letter in
the standard font, for example, the text that is derived from $\slp{S}_i$ is denoted by $S_i$.

The \emph{size} of an SLP $\slp{S}$ is the number of its rules and is denoted by $|\slp{S}|$. The \emph{concatenation}
of SLPs $\slp{S}_1$ and $\slp{S}_2$ is an SLP that derives $S_1 \cdot S_2$ and denoted by $\slp{S}_1 \cdot \slp{S}_2$.
The \emph{cut position} of a nonterminal rule $\slp{S}_i = \slp{S}_\ell\cdot \slp{S}_r$ is the position $|S_\ell|$ in
the text $S_i$. For instance, the cut position of $\slp{F}_4$ in the example in Figure~1 is equal to~2. For every
terminal rule we define its cut position to be equal to~0.

\begin{figure}[t]
	\FibonacciWordSLP
\end{figure}

\section{Basic operations}

In this section we present some basic operation over SLPs widely used in the paper.

\subsection{Subgrammar cutting}

\problem{SubCut}{an SLP $\slp{S}$ that derives text $S$ and $0 \leq \ell < r \leq |\slp{S}| $ are integers;}{an SLP
$\slp{S}\substr{\ell}{r}$ that derives text $S\substr{\ell}{r}$;}

\noindent {\sc Algorithm:} The algorithm descends from the root of $\slp{S}$ to a son that touches both positions $\ell$
and $r$ while it finds a rule $\slp{S}'$ such that $\slp{S}'$ is a terminal rule or a nonterminal rule that left son
touches only $\ell$ and right son touches only $r$. Notice that original values of $\ell$ and $r$ may change during the
process. If $\slp{S}'$ is a terminal rule then the algorithm returns $\slp{S}'$. Let $\slp{S}' = \slp{L} \cdot \slp{R}$
be a nonterminal rule and $\gamma$ be a cut position of $\slp{S}'$. The algorithm decompose $\slp{L}$ into rules
$\slp{L}_p, \dots, \slp{L}_1 \in \slp{L}$ such that $\slp{L}_p \cdot \mbox{\dots} \cdot \slp{L}_1$ derives
$S\substr{\ell}{\gamma}$ and decompose $\slp{R}$ into rules $\slp{R}_1, \dots, \slp{R}_q \in \slp{R}$ such that
$\slp{R}_1 \cdot \mbox{\dots} \cdot \slp{R}_q$ derives $S\substr{\gamma}{r}$. At Figure 2 presented pseudo code that
illustrate how the algorithm obtains $\slp{L}_p, \dots, \slp{L}_1$. The set of rules $\slp{R}_1, \dots, \slp{R}_q$ obtains similarly.

\SubCutPseudoCode

Finally the algorithm concatenates two set of rules into a single SLP in the following order: $$\slp{L}_p \cdot
(\slp{L}_{p-1} \cdot \mbox{\dots} \cdot (\slp{L}_1 \cdot (\slp{R}_1 \cdot \mbox{\dots} \cdot (\slp{R}_{q-1} \cdot
\slp{R}_q) ) ) ).$$

\noindent \textsc{Complexity:} To find a rule $\slp{S}'$ the algorithm descends along a path between the root of
$\slp{S}$ and some leaf of $\slp{S}$ at worst case, so the algorithm needs $O(|\slp{S}|)$ time. To decompose $\slp{L}$
into rules $\slp{L}_p, \dots, \slp{L}_1$ the algorithm descends along a path between the root of $\slp{L}$ and some leaf
of $\slp{L}$ at worst case, so the algorithm needs $O(|\slp{L}|)$ time. Similarly the algorithm needs $O(|\slp{R}|)$ time
to decompose $\slp{R}$ into rules $\slp{R}_1, \dots, \slp{R}_q$. Altogether there is algorithm that solves
\textbf{SubCut} problem using $O(|\slp{S}|)$ time and $O(|\slp{S}|)$ space.

\subsection{Pattern matching}

\problem{PM}{SLP's $\slp{S}, \slp{T}$ such that $|S| \leq |T|$;}{$O(|\slp{T}|)$ arithmetic progressions that describe
start positions of all occurrences $S$ in $T$;}

\begin{thm}[{\rm\cite{15}}]
There is algorithm that solves \textbf{PM} problem using $O(|\slp{T}|^2|\slp{S}|)$ time and $O(|\slp{T}||\slp{S}|)$
space.
\end{thm}

\subsection{Substrings extending}

\problem{SubsExt}{an SLP $\slp{S}$ and integers $\ell_1, r_1, \ell_2, r_2 (0 \leq \ell_1 < r_1 \leq |\slp{S}|, 0 \leq
\ell_2 < r_2 \leq |\slp{S}|)$ such that $S\substr{\ell_1}{r_1} = S\substr{\ell_2}{r_2}$;}{integers $\ell_{ex}$ and
$r_{ex}$, where $\ell_{ex}$ is the length of the longest common suffix of $S\substr{1}{r_1}$ and $S\substr{1}{r_2}$,
$r_{ex}$ is the length of the longest common prefix of $S\substr{\ell_1}{|S|}$ and $S\substr{\ell_2}{|S|}$;}

\vspace{2pt}

\noindent \textsc{Algorithm:} The algorithm obtains $r_{ex}$ by induction.

\vspace{2pt}

\noindent \textsc{Base:} The algorithm set $r_{ex}$ is equal to $\min \{|S| - r_1, |S| - r_2\}$. Using \textbf{SubCut}
problem the algorithm constructs $\subslp{S}{r_1}{r_1 + r_{ex}}$ and $\subslp{S}{r_2}{r_2 + r_{ex}}$.  Next it runs
\textbf{PM} problem with the SLPs as input. If the result set is not empty then algorithm stops. Otherwise it sets
$step = \lfloor \frac{r_{ex}}{2} \rfloor$ and $r_{ex} = 0$.

\vspace{2pt}

\noindent \textsc{Step:} Using \textbf{SubCut} problem the algorithm constructs $\subslp{S}{r_1}{r_1 + r_{ex} + step}$
and $\subslp{S}{r_2}{r_2 + r_{ex} + step}$.  Next it runs \textbf{PM} problem with the SLPs as input. If the result set
is not empty then the algorithm sets $r_{ex} = r_{ex} + step$ and $step = step + \lceil \frac{step}{2} \rceil$.
Otherwise it sets $step = step - \lceil \frac{step}{2} \rceil$.

The algorithm obtains $\ell_{ex}$ analogously.

\vspace{2pt}

\noindent \textsc{Complexity:} There are $O(\log |S|)$ steps. At each step the algorithm runs \textbf{SubCut} problem
two times and \textbf{PM} problem one time. Totally it needs $O(|\slp{S}|^3)$ time and $O(|\slp{S}|^2)$ space for each
step. Altogether there is algorithm that solves \textbf{SubsExt} problem $O(|\slp{S}|^3 \log|S|)$ time and
$O(|\slp{S}|^2)$ space.

Using \textbf{SubsExt} problem we can easy solve the following problem:

\problem{Period termination}{an SLP $\slp{S}$, an integer $p > 0$ and positions $0 \leq \ell < r \leq |\slp{S}|$ such that
$S\substr{\ell}{r}$ is $p$-periodic substring;}{$t_L, t_R$ are positions in the text $S$ where $p$-periodicity of
$S\substr{\ell}{r}$ terminates from the left and from the right correspondingly;}

\vspace{2pt}

\noindent \textsc{Algorithm:} Using \textbf{SubCut} problem the algorithm constructs SLP $\slp{P}$ that derives
$S\substr{\ell}{\ell + p}$. Let $k$ be an odd integer that $p^k > |S|$. Using $\Theta(\log k)$ time the algorithm constructs
SLP $\slp{P}^k$ that derives $S\substr{\ell}{\ell+p}^k$. Finally it runs \textbf{SubsExt} problem with the following parameters:
$\slp{S} \cdot \slp{P}^k$, $\ell_1 = \ell, r_1 = r, \ell_2 = |S| + p \cdot \frac{k-1}{2}, r_2 = |S| + p \cdot \frac{k-1}{2} + (r
- \ell)$.

\vspace{2pt}

\noindent \textsc{Complexity:} The algorithm runs \textbf{SubCut} problem one time. Next it spends $\log k \leq \log
|S|$ operations to construct $\slp{P}^k$. Finally in runs \textbf{SubsExt} problem one time. Altogether there is
algorithm that solves \textbf{Period termination} problem using $O(|\slp{S}|^3 \log|S|)$ time and
$O(|\slp{S}|^2)$ space.

%TODO move to SAPS algorithm section
\subsection{Purity check}

\problem{Purity check}{an integer $p > 0$ and an SLP $\slp{S}$ such that $|S| \geq 2p$ and for every position $c \in
\overline{p \dots |S| - p}$ $S\substr{c-p}{c+p}$ is a repetition;}{\textbf{true}, if all the
repetitions are pure squares, otherwise \textbf{false};}

\begin{lem}[{\rm\cite{2}}]
A family of repetitions contains a pure square if and only if all the repetitions in the family are pure squares.
\end{lem}

If square $xx$ is not pure then $x$ contains at least one pure square. It follows form definition of pure square. To
solve \textbf{Purity check} problem enough to check whether exists pure square that belongs to $S\substr{\ell - |x|}{\ell}$.

Sketch:

The algorithm starts from root of $\slp{S}$ and recursively goes down in parse tree of $\slp{S}$.

\section{The algorithm}

\subsection{Idea of pure squares location}

Let us fix a rule $\slp{S}_j = \slp{S}_l \cdot \slp{S}_r$ and its cut position $\gamma$. There exists a number
$i_0$ such that $2^{i_0} \geq \max\{|S_l|, |S_r|\}$. Let us fix a number $i \in \{ 1, \dots, i_0 \}$. So for
every pair $(j, i)$ the algorithm looks for the following set of pure squares: $\{xx \ | \ |x| \in
[2^{i-1}, 2^i-1] \mbox{ and $xx$ touches $\gamma$}\}$.

\noindent \textsc{Correctness:} Let us show that the algorithm doesn't miss any pure square by contradiction. Let $xx$
be a pure square that was not found using the search algorithm. Let $\ell, r$ be left and right position of $xx$ in the
text $S$. Using $O(|\slp{S}|)$ time we can obtain a rule $\slp{S}_j$ that $S_j$ fully contains $xx$ and $xx$ touches cut
position of $\slp{S}_j$ (just walk down from root of $\slp{S}$ while not found a first rule that cut position is in
$[\ell, r]$). There exist number $i$ that $|x| \in [2^{i-1}, 2^i-1]$. Since $xx$ touches $\gamma$ and $|xx| < 2^{i+1}$
then $xx$ belongs to $2^{i+1}$-environment of $\gamma$. So we have contradiction with condition that for fixed rule
$\slp{S}_j$ and number $i$ we able to found all pure squares.

\subsection{Idea of local search}

Let partition the $2^{i+1}$-environment of $\gamma$ into 16 text blocks of equal length. Thus the length of each
block is $2^{i-2}$. Partition starts from $\gamma$ so leftmost and rightmost blocks in the partition may have
length less than $2^{i-2}$. Let us enumerate the blocks from $B_1$ to $B_{16}$. Notice centers of pure squares
should locate at blocks from $B_5$ to $B_{12}$ otherwise we get contradiction with length of pure square or
touching $\gamma$.

Let $c$ be center of a pure square $xx$ and it belongs to one of the eight blocks $B_k$. Since $|x| \geq 2^{i-1}$
then $xx$ should contain at least three consecutive blocks $B_{k-1}, B_{k}$ and $B_{k+1}$. For example, let $c$
belong to block $B_7$ then $xx$ must contains blocks $B_6$ and $B_8$. Let us fix $B_{k-1}$. Using pattern matching
algorithm we able to find all occurrences of $B_{k-1}$ in $B_{k+1}\cdot B_{k+2}$. Next the algorithm take pair of
blocks ($B_{k-1}$ and its occurrence in $B_{k+1}\cdot B_{k+2}$) and extend both to check whether or not they form
a square.

\noindent \textsc{Correctness:} Let us show correctness of the idea by contradiction. Let $xx$ be a pure square that
fully contains in $S_j$, touches $\gamma$ and $|x| \in [2^{i-1}, 2^i-1]$. Suppose $xx$ was not found using the search
algorithm. Let $c$ be a center of $xx$. If $c$ not belong to blocks from $B_5$ to $B_{12}$ then we have contradiction
as shown above. Let $c$ belong to block $B_k$ where $k\in \{ 5, \dots, 12 \}$. If two adjacent blocks of $B$ not
belong to $xx$ then we have contradiction with length of $xx$. Since $|x| \geq 2^{i-1}$ then $xx$ contains at least
three consecutive blocks of the partition. Let $B_{k-1}$ is one of two adjacent blocks. If start position of occurrence
of $B_{k-1}$ belong to $B_k$ then $|x| < 2\cdot 2^{i-2} < 2^{i-1}$ that contradicts with $|x| \in [2^{i-1},2^i-1]$. If
start position of occurrence of $B_{k-1}$ belong to $B_{k+3}$ (or even greater) then $|x| > 4\cdot 2^{i-2} > 2^i-1$
that contradicts with $|x| \in [2^{i-1},2^i-1]$ also. Otherwise we have contradiction with condition that we able to
find all pure squares between a block and its occurrences in some area.

\subsection{Square-freeness problem}

\problem{Square-freeness}{an SLP $\slp{S}$ that derives text $S$;}{Whether or not $S$ is square-free?}

The following lemma is helpful for solving square-freeness problem:

\begin{lem}[{\rm\cite{2}}]
Assume that the period of a string $B$ is $p$. If $B$ occurs only at positions $p_1 < p_2 < \dots < p_k$ of a text
$S$ and $p_k - p_1 \leq \frac{|B|}{2}$ then the $p_i$'s form an arithmetic progression with difference $p$.
\end{lem}

\SquareFreenessCode

So for every block $B_{k-1}$ we obtain all occurrences of $B_{k-1}$ in $B_{k+1}\cdot B_{k+2}$. From the lemma
above follows that we can represent all occurrences using four arithmetic progressions. Therefore we need to check
whether on not block $B_{k-1}$ and progression $\prog{a}{p}{t}$ of its occurrences form a square? We propose the following
algorithm for the check:

\begin{itemize}
\item If $t = 0$ then there are no squares. The algorithm moves to the next block;

\item If $t = 1$ then we obtain $\ell_{ex}$, $r_{ex}$ using \textbf{SubsExt} problem for $B_{k-1}$ and $S_j[a\dots a +
2^{i-2}]$. If $\ell_{ex} + r_{ex} > a - (k-1)\cdot 2^{i-2}$ then there exist at least one square and the  algorithm returns
$\bf{false}$. Otherwise there are no squares and the algorithm moves to the next block;

\item If $t \geq 2$ there exists at least one square. The algorithm returns $\bf{false}$.
\end{itemize}

Pseudo code for square-freeness checking presented at figure 3.

\begin{thm}
There is algorithm that solves square-freeness problem using $O(|\slp{S}|^4\cdot \log^2{|S|})$ time and $O(|\slp{S}|^2)$ space.
\end{thm}

\subsection{PS-table}

The \emph{pure squares table} (PS-table) is a rectangular table $PS(\slp{S})$ that stores information about all pure
squares in the text in a compressed form. The size of $PS(\slp{S})$ is equal to $(\lfloor\log |S|\rfloor+1) \times
(|\slp{S}|+1)$. It is convenient to start numbering of rows and columns of PS-tables with 0. We denote the cell in
the $i$-th row and $j$-th column of table by $PS(i,j)$. The cell $PS(0,0)$ is always left blank. The cells $PS(0,j)$
with $j>0$ contain the rules of the SLP $\slp{S}$ ordered such that the lengths of the texts they derive increase. (If some
rules derive texts of the same length then the rules are listed in an arbitrary but fixed order). Thus, the first cells
of the 0-th row contain terminal rules followed by rules that derive texts of length~2, etc.  The cells $PS(i,0)$ with
$i>0$ contain segments $[2^{i-1}, 2^i - 1]$. In every cell $PS(i, j)$ with $i,j>0$, we shall store information about
families of pure squares. There exist three types of stored families:

\begin{itemize}
  \item empty family (stored as $\emptyset$);
  \item family of pure squares with fixed root length (stored using triple $\{|x|, c_l, c_r \}$ where $|x|$ is length
  of root, $c_l$ is center position of leftmost pure square in $\slp{S}_j$, $c_r$ is center position of rightmost pure
  square in $\slp{S}_j$);
  \item family of pure squares with float root length;
\end{itemize}

The reader may wish to look at the example of the PS-table for the SLP $\slp{F}_7$ in Appendix~A in which all square
families has fixed root length.

Once a PS-table is constructed, it is easy to solve the following problems:

\begin{itemize}
  \item to find information about all pure squares of fixed length;
  \item to compute the number of pure squares that are contained in $S$.
\end{itemize}

More complicated questions also can be answered. For instance, suppose we are given SLPs $\slp{S}$ and $\slp{P}$ such
that $\slp{P}$ derives a pure square $xx$. The question is whether or not $xx$ occurs in the text $S$?

Sketch of algorithm:

The algorithm computes length of $xx$ using $O(|\slp{P}|)$ time. Next it find a row of the PS-table such that
$2^{i-1} < |x| < 2^i$ using $O(\log{|S|})$ time. Finally the algorithm checks whether $xx$ belongs to a family encoded
in any cell of the row. Obviously the algorithm skip empty families. The following cases are remained to be
considered:

\begin{itemize}
  \item the algorithm process the following family: $\{|y|, c_l, c_r\}$. If $|x| \neq |y|$ then the algorithm moves to
  the next family. Otherwise it take subgrammar $\slp{S}\substr{c_l - |x|}{c_r + |x|}$ using $O(|\slp{S}|)$ time and run
  pattern matching algorithm on $\slp{S}\substr{c_l - |x|}{c_r + |x|}$ and $\slp{P}$ using $O(|\slp{P}|^3)$ time.
  \item the algorithm process the following family: $k, \prog{a}{p}{t}, \alpha_L, \alpha_R, \gamma_L, \gamma_R$. If
  there is no integer $t' \in \overline{0 \dots t}$ such that $t' = \frac{|x| - a + (k-1) \cdot 2^{i-2} }{p}$ or $|x|
  \geq \min(\alpha_R -\alpha_L, \gamma_R - \gamma_L)$ then the algorithm moves to the next family. Otherwise the
  family reduced to family with fixed root length $\{|x|, \max(\alpha_L + |x|, \gamma_L) + 1, \min(\alpha_R,
  \gamma_R - |x|)\}$ and processed as shown above.
\end{itemize}

If the algorithm find match at some family then it immediately stops and return \textbf{true}. If the algorithm find no
match checking all families in the row then it return \textbf{false}.

In the worst case we need $O(\max\{ |\slp{S}|, \log |S|\} \cdot |\slp{P}|^3)$ time. Moreover, we can modify the
algorithm to save information about all occurrences of $xx$ in $S$. Clearly, the general pattern matching algorithm also
solves these problem, but it needs $O(|\slp{P}||\slp{S}|^2)$ time. Therefore using information from the PS-table will be
more effective if $|\slp{S}|$ much larger than $|\slp{P}|$.

Another natural problem is the following. Let an SLP $\slp{S}$ derive the text $S$ and let a position $i$ be fixed.
The problem is to construct an SLP that derives all pure squares starting from the position $i$ in $S$. (Since by the
definition each SLP derives only one string, we mean here an SLP that derives a string consisting of all pure squares
in question separated by a new symbol.)  Altogether there are $O(\log|\slp{S}|)$ rules that contain $i$.

\begin{lem}[{\rm\cite{11}}]
If there are three squares $xx, yy, zz$ with $|x| < |y| < |z|$ that start at the same position of some string, then $|x|
+ |y| \leq |z|$.
\end{lem}

The lemma implies that for every interval of lengths there exist at most two squares starting from an arbitrary
position. Therefore altogether there are $O(|\slp{S}|)$ pure squares starting at a particular position. So we can
gather information about all pure squares in an explicit form. We can build an SLP that derives all pure squares
starting in a particular position in $O(|\slp{S}|^2)$ time using the substring taking algorithm.

\subsection{Searching all pure squares problem}

Remind the main problem:

\problem{Searching all pure squares}{an SLP $\slp{S}$ that derives text $S$;}{a compressed presentation of all
pure squares in $S$;}

To solve the problem remain to recognize all pure squares between a block $B_k$ and an arithmetic progression
$\prog{a}{p}{t}$ of its occurrences. Since $t$ can be exponentially large relative to $|\slp{S}|$ the algorithm
cannot consecutively check every occurrence of $B_k$.

Let $\alpha_L, \alpha_R$ be output of \textbf{Period termination} problem for $\slp{S}_j, B_k =
S_j\substr{(k-1)\cdot2^{i-2}}{k\cdot 2^{i-2} -1}$. $\alpha_L, \alpha_R$ called \emph{defined} if they satisfies
the following inequalities: $(2k-1)\cdot2^{i-2} - (a + p\cdot t) \leq \alpha_L$, $\alpha_R < a + 2^{i-2}$.
Otherwise they are called \emph{undefined}. Since $2^{i} - 1$ is the greatest length of a root then start
positions of pure squares can not be further right than $(2k-1)\cdot2^{i-2} - (a + p\cdot t)$. So it does not
matter where the $p$-periodicity terminates outside. Analogously $\gamma_L, \gamma_R$ defined as output of
\textbf{Period termination} problem for $\slp{S}_j, S_j\substr{a}{a + p\cdot t}$. $\gamma_L, \gamma_R$  called
\emph{defined} if they satisfies the following inequalities: $(k-1)2^{i-2} \leq \gamma_L$ and $\gamma_R < 2(a + p\cdot
t) - (k-1)2^{i-2}$. Otherwise they are called \emph{undefined}.

For the positions $\alpha_L, \alpha_R, \gamma_L$ and $\gamma_R$ the following lemmas are valid:

\begin{lem}[{\rm\cite{2}}]
If one of $\alpha_R$ or $\gamma_L$ is defined, then the other one is defined, and $\alpha_R - \gamma_L \leq p$.
\end{lem}

\begin{lem}[{\rm\cite{2}}]
If both $\alpha_R$ and $\gamma_L$ are undefined, then none of the repetitions possible containing $B_k$ are a
square.
\end{lem}

Therefore squares exists if and only if $\alpha_R$ and $\gamma_L$ are defined. Let us consider possible relative
positions of $\alpha_R$ and $\gamma_L$:
\begin{itemize}
\item If $\alpha_R < \gamma_L$ then centers of pure squares may located at $[k \cdot 2^{i-2}, \alpha_R]$, $(\alpha_R, \gamma_L]$,
$(\gamma_L, (k+1)\cdot2^{i-2}]$;
\item If $\alpha_R > \gamma_L$ then centers of pure squares may located at $[k \cdot 2^{i-2}, \gamma_L]$, $(\gamma_L, \alpha_R]$,
$(\alpha_R, (k+1)\cdot2^{i-2}]$;
\end{itemize}

Most cases (except $(\gamma_L, \alpha_R]$) can be solved using the following lemma:

\begin{lem}[{\rm\cite{2}}]
If both $\alpha_R, \gamma_L$ are defined then:

\begin{enumerate}
\item Repetitions that are contain $B_k$ and centered at positions $h$, such that $h \leq \gamma_L$, may exist only if
$\alpha_L$ is defined. These repetitions constitute a family of repetitions that corresponds to the difference
$|x| = a + t'\cdot p - (k-1)2^{i-2}$, provided that there exists some $t' \in \overline{0\dots t}$ such that
$\gamma_L - \alpha_L = a + t'\cdot p - (k-1)2^{i-2}$.
\item Repetitions that are contain $B_k$ and centered at positions $h$, such that $\alpha_R < h$, may exist only if
$\gamma_R$ is defined. These repetitions constitute a family of repetitions that corresponds to the difference
$|x| = a + t''\cdot p - (k-1)2^{i-2}$, provided that there exists some $t'' \in \overline{0\dots t}$ such that
$\gamma_L - \alpha_L = a + t''\cdot p - (k-1)2^{i-2}$.
\end{enumerate}
Notice that if $\alpha_R < \gamma_L$, then repetitions whose center $h$ satisfies $\alpha_R < h \leq\gamma_L$ may
exist only if both $\alpha_L$ and $\gamma_R$ are defined and $\gamma_R - \alpha_R = \gamma_L - \alpha_L$.
\end{lem}

At each case of the previous lemma the algorithm may obtain exponentially many repetitions. Therefore it stores in
compressed way: $\{|x|, c_l, c_r\}$ where $|x|$ is length of the root, $c_l$ is center of leftmost repetition,
$c_r$ is center of rightmost repetition. So if $\alpha_R < \gamma_L$ the algorithm may obtain the following three
families of repetitions at worst case: $\{\gamma_L - \alpha_L, k \cdot 2^{i-2}, \alpha_R\}, \{\gamma_R - \alpha_R,
\alpha_R + 1, \gamma_L\}, \{\gamma_L - \alpha_L, \gamma_L + 1, \min\{a,(k+1) \cdot 2^{i-2}\}\}$. Else the algorithm may
obtain the following two families of repetitions at worst case: $\{\gamma_L - \alpha_L, k \cdot 2^{i-2}, \gamma_L - 1\},
\{\gamma_R - \alpha_R, \alpha_R, \min\{a,(k+1) \cdot 2^{i-2}\}\}$.

The last case can be solved using the following lemma:

\begin{lem}[{\rm\cite{2}}]
If $\alpha_R, \gamma_L$ are defined and $\gamma_L < \alpha_R$, then there might be a family of repetitions
associated with each of the differences $|x| = a + p\cdot t' - (k-1)\cdot 2^{i-2}$ where $t' \in \overline{0\dots t}$,
with centers at positions $h$, such that $\gamma_L < h \leq \alpha_R$. The repetitions in each such family are all
pure squares, and they are centered at positions $h$, such that $\max(\alpha_L + |x|, \gamma_L) < h \leq
\min(\alpha_R, \gamma_R-|x|)$. Notice that such a family is not empty only if $|x| < \min(\alpha_R-\alpha_L,
\gamma_R-\gamma_L)$.
\end{lem}

Since families of pure squares have float centers and float length of root the algorithm store it exactly:
$k, \prog{a}{p}{t}, \alpha_L, \alpha_R, \gamma_L, \gamma_R$.

Pseudo code of the algorithm presented at figure 4.

\SearchingPureSquaresCode

\begin{thm}
There is algorithm that solves Searching all pure squares problem using $O(|\slp{S}|^4 \cdot \log^2{|S|})$ time and
$O(|\slp{S}| \cdot \max(|\slp{S}|, \log{|S|}))$ space.
\end{thm}

\section{Conclusion}

We have presented an algorithm that, given an SLP $\slp{S}$ deriving a text $S$, fills out a table containing
information about all pure squares that occur in $S$ in time $O(|\slp{S}|^4\cdot \log^2{|S|})$ using
$O(|\slp{S}|\cdot \max\{ |\slp{S}|, \log{|S|}\})$ space. We would like to emphasize some features of the
algorithm:

\begin{itemize}
\begin{item}
This algorithm is divided into independent steps in contrast to classical algorithms in this area which
consecutively accumulate information about required objects. As a result it can be parallelized.
\end{item}
\begin{item}
The algorithm is quite difficult from the viewpoint of practical implementation. Also it is not excluded that the
constants hidden in the ``$O$'' notation  are actually very big.
\end{item}
\end{itemize}

\bibliography{saps_journal}{}
\bibliographystyle{plain}

\begin{appendix}
\section{Examples}

\subsection{Leech word square-freeness}
Let us consider the SLP $\slp{L}$ that derives substring of Leech square free word:

\begin{center}
$\slpterm{L}{1}{a}, \slpterm{L}{2}{b}, \slpterm{L}{3}{c}, \slpnonterm{L}{4}{2}{3}, \slpnonterm{L}{5}{2}{1},
\slpnonterm{L}{6}{1}{4}$

$\slpnonterm{L}{7}{3}{4}, \slpnonterm{L}{8}{6}{5}, \slpnonterm{L}{9}{8}{4}, \slpnonterm{L}{10}{8}{7},
\slpnonterm{L}{11}{10}{9}$
\end{center}

Parse tree for $\slp{L}$ presented at figure 4.

\begin{figure}[th]
\LeechSLP
\end{figure}

Let us check square freeness of $\slp{L}$. Since $|L| = 15$ then the algorithm check the following segments of root
length: [1, 1], [2, 3], [4, 7]. Notice that rules of $\slp{L}$ already ordered by length of derived text.

\begin{itemize}
  \item \textbf{checking square freeness of squares that root length equals to 1}

  Firstly the algorithm skip terminal rules. Next it consecutively look for squares exactly in other rules. For
  instance, let us consider how it checks $\slpnonterm{L}{10}{8}{7}$. The algorithm find $L_8[5] = a$ and $L_7[1] = c$
  using $\slp{L}_{10}$. Since $a \neq c$ it moves to $\slp{L}_{11}$.

  It is clear that $\slp{L}_4, \dots, \slp{L}_{11}$ have no squares of length 2 around its cut positions.
  \item \textbf{checking square freeness of squares that root length belong to [2, 3]}

  The algorithm skip all rules that have length less 4 (i.e. $\slp{L}_1, \dots, \slp{L}_7$). For instance, let us
  consider how it checks $\slpnonterm{L}{8}{6}{5}$. Since $|L_8| = 5$ and block length is equal to 1 then the algorithm
  construct an SLP $\slp{L}_8'$ that derives text \emph{\$~\$~\$~\$~\$~a~b~c~b~a~\$~\$~\$~\$~\$~\$}, where \emph{\$} is
  special symbol not from $\Sigma$. At figure 5 presented partition of $L_8'$ into blocks of length 1.

  \LeechWordPartitionSimple

  Remind that the algorithm necessary to check blocks $B_5, \dots, B_{12}$. It no need to check $B_5$ since it contains
  \emph{\$}. Also it no need to check $B_9$ and $B_{10}$ since the search area is out of $L_8$. For instance, let us
  consider how it checks $B_7$. The algorithm build $\slp{L}_8'\substr{6}{7}$ that derives $B_7$ and
  $\slp{L}_8'\substr{8}{11}$ that derives search area $B_9 \cdot B_{10}$. Next it runs pattern matching algorithm on
  $\slp{L}_8'\substr{6}{7}$, $\slp{L}_8'\substr{8}{11}$ and obtain occurrence of $B_7$ at position 9 of $L_8'$. Finally
  it runs \textbf{SubsExt} problem with the following parameters: $\slp{L}_8'$ and positions 6, 7, 8, 9. The algorithm
  obtains $\ell_{ex} = r_{ex} = 0$. Since $\ell_{ex} + r_{ex} = 0 = a - (k - 1) \cdot 2^{i-2} = 8 - (9 - 1) \cdot 1$ then
  algorithm moves to $L_9$.

  \item \textbf{checking square freeness of squares that root length belongs to [4, 7]}

  The algorithm skip all rules that have length less 8 (i.e. $\slp{L}_1, \dots, \slp{L}_9$). For instance, let us
  consider how it checks $\slpnonterm{L}{11}{10}{9}$. Firstly it construct an SLP $\slp{L}_{11}'$ that derives $L$
  surrounded with \emph{\$} and $|L_{11}'| = 32$. At figure 6 presented partition of $L_{11}'$ into blocks of length
  2.

  \LeechWordPartitionComplex

  Next the algorithm find no squares for $B_5, \dots, B_8$ since pattern matching algorithm returns empty set of
  results. Next the algorithm find occurrence of $B_9$ at position 22 of $L_{11}'$ and run \textbf{SubsExt}
  problem with the following parameters: $\slp{L}_{11}'$ and positions 16, 18, 20, 22. Since $\ell_{ex} = r_{ex} = 0$ the
  algorithm moves to $B_{10}$. Finally the algorithm find no squares for $B_{10}, B_{11}, B_{12}$ since correspond
  search areas contains \emph{\$}.
\end{itemize}

\subsection{Construction PS-table for $\slp{F}_7$}

Let us consider how the algorithm construct PS-table for $\slp{F}_7$ that derives text \emph{a~b~a~a~b~a~b~a~a~b~a~a~b}.
The PS-table size is equal to $(\lfloor\log |F_7|\rfloor+1)\times (|\slp{F}_7|+1) = 4 \times 8$.

\begin{itemize}
  \item \textbf{looking for squares that root length equals to 1}

  Firstly the algorithm mark cells with $\varnothing$ for rules with length less than 2. Next it consecutively look for
  squares exactly in other rules. PS(1, 3) = $\varnothing$ since $F_1[1] = a \neq b = F_2[1]$. Analogously PS(1, 4) =
  PS(1, 6) = $\varnothing$. PS(1, 5) = \{1, 3, 3\} since $F_4[3] = a = F_3[1]$. PS(1, 7) = \{1, 8, 8\} since $F_6[8] = a
  = F_5[1]$. After first step PS-table has the following view:

  \begin{figure}[h]
	  {\footnotesize\noindent
		\begin{tabular}{|c|c|c|c|c|c|c|c|} \hline
	 	& $\slpterm{F}{1}{a}$ & $\slpterm{F}{2}{b}$ & $\slpnonterm{F}{3}{1}{2}$ & $\slpnonterm{F}{4}{3}{1}$ &
	 	$\slpnonterm{F}{5}{4}{3}$ & $\slpnonterm{F}{6}{5}{4}$ & $\slpnonterm{F}{7}{6}{5}$ \\ \hline

	 	[1, 1] & $\varnothing$ & $\varnothing$ & $\varnothing$ & $\varnothing$ & \{1, 3, 3\} & $\varnothing$ & \{1, 8, 8\} \\
	 	\hline

	 	[2, 3] & & & & & & & \\ \hline

	 	[4, 7] & & & & & & & \\ \hline
		\end{tabular}
	  }
  \end{figure}

  \item \textbf{looking for squares that root length belongs to [2, 3]}

  The algorithm mark cells with $\varnothing$ for rules with length less than 4. For instance, let us consider
  how the algorithm fill PS(2, 6). The algorithm construct SLP $\slp{F}_6'$ that derives text
  \emph{\$~\$~\$~a~b~a~a~b~a~b~a~\$~\$~\$~\$~\$} of length 16. At figure 7 presented partition of $F_6'$ into blocks.

  \FibonacciWordPartition

  $B_5$: using \textbf{PM} problem the algorithm obtain occurrence of $B_5$ at position 8 of $F_6'$ on
  $\slp{F}_{6}'\substr{5}{6}, \slp{F}_{6}'\substr{7}{9}$; the substring extending algorithm obtain $\ell_{ex} = r_{ex} = 1$
  on $\slp{F}_{6}'$ with parameters 5, 6, 8, 9; so family of repetitions \{3, 7, 7\} was found;

  $B_6$: using \textbf{PM} problem the algorithm obtain occurrence of $B_6$ at position 9 of $F_6'$ on
  $\slp{F}_{6}'\substr{6}{7}, \slp{F}_{6}'\substr{8}{10}$; the substring extending algorithm obtain $\ell_{ex} = 2, r_{ex}
  = 0$ on $\slp{F}_{6}'$ with parameters 6, 7, 9, 10; so family of repetitions \{3, 7, 7\} was found;

  $B_7$: using \textbf{PM} problem the algorithm obtain occurrence of $B_7$ at position 9 of $F_6'$ on
  $\slp{F}_{6}'\substr{7}{8}, \slp{F}_{6}'\substr{9}{11}$; the substring extending algorithm obtain $\ell_{ex} = 0, r_{ex}
  = 1$ on $\slp{F}_{6}'$ with parameters 7, 8, 9, 10; so no family of repetitions was found;

  $B_8$: using \textbf{PM} problem the algorithm obtain occurrence of $B_8$ at position 10 of $F_6'$ on
  $\slp{F}_{6}'\substr{8}{9}, \slp{F}_{6}'\substr{10}{12}$; the substring extending algorithm obtain $\ell_{ex} = r_{ex}
  = 1$ on $\slp{F}_{6}'$ with parameters 8, 9, 10, 11; so family of repetitions \{2, 8, 9\} was found;

  $B_9$: using \textbf{PM} problem the algorithm obtain occurrence of $B_9$ at position 11 of $F_6'$ on
  $\slp{F}_{6}'\substr{9}{10}, \slp{F}_{6}'\substr{11}{13}$; the substring extending algorithm obtain $\ell_{ex} = 1,
  r_{ex} = 0$ on $\slp{F}_{6}'$ with parameters 9, 10, 11, 12; so family of repetitions \{2, 9, 9\} was found;

  The algorithm skip blocks $B_{10}, \dots, B_{12}$ since the search area consist of \emph{\$}. After merging families
  of repetitions the algorithm have the following result: \{3, 7, 7\}, \{2, 8, 9\}. Finally the algorithm check purity
  of families and shift them form $F_{6}'$ to $F_6$.

  After second step PS-table has the following view:

  \begin{figure}[h]
	  {\footnotesize\noindent
		\begin{tabular}{|c|c|c|c|c|c|c|c|} \hline
	 	& $\slpterm{F}{1}{a}$ & $\slpterm{F}{2}{b}$ & $\slpnonterm{F}{3}{1}{2}$ & $\slpnonterm{F}{4}{3}{1}$ &
	 	$\slpnonterm{F}{5}{4}{3}$ & $\slpnonterm{F}{6}{5}{4}$ & $\slpnonterm{F}{7}{6}{5}$ \\ \hline

	 	[1, 1] & $\varnothing$ & $\varnothing$ & $\varnothing$ & $\varnothing$ & \{1, 3, 3\} & $\varnothing$ & \{1, 8, 8\} \\
	 	\hline

	 	[2, 3] & $\varnothing$ & $\varnothing$ & $\varnothing$ & $\varnothing$ & $\varnothing$ & \{3, 4, 4\}, \{2, 5, 6\} &
	 	\{3, 10, 10\} \\ 	\hline

	 	[4, 7] & & & & & & & \\ \hline
		\end{tabular}
	  }
  \end{figure}

  \item \textbf{looking for squares that root length belongs to [4, 7]}

  The algorithm mark cells with $\varnothing$ for rules with length less than 8. The algorithm construct SLP
  $\slp{F}_7'$ that surrounds with \emph{\$} and has length 32. At figure 8 presented partition of $F_7'$ into
  blocks. Let us consider how the algorithm fill PS(3, 7). It skips $B_5$ since $B_5$ contains \emph{\$}.

   \FibonacciWordPartitionComplex

  $B_6$: using \textbf{PM} problem the algorithm obtain occurrence of $B_6$ at position 15; the substring extending algorithm
  obtain $\ell_{ex} = 1, r_{ex} = 3$ on $\slp{F}_{7}'$ with parameters 10, 12, 14, 18; so family of repetitions \{5, 14,
  15\} was found;

  $B_7$: using \textbf{PM} problem the algorithm obtain occurrence of $B_7$ at position 17; the substring extending algorithm
  obtain $\ell_{ex} = 3, r_{ex} = 1$ on $\slp{F}_{7}'$ with parameters 12, 14, 16, 20; so family of repetitions \{5, 14,
  15\} was found;

  $B_8$: using \textbf{PM} problem the algorithm obtain occurrence of $B_8$ at position 20; the substring extending algorithm
  obtain $\ell_{ex} = r_{ex} = 0$ on $\slp{F}_{7}'$ with parameters 14, 16, 18, 22; so there are no families of
  repetitions;

  $B_9$: using \textbf{PM} problem the algorithm obtain no occurrence of $B_9$; so there are no families of repetitions;

  The algorithm skips $B_{10}$ and $B_{11}$ since search areas consist of \emph{\$}. It skips $B_{12}$ since $B_{12}$
  contains \emph{\$}. After merging families of repetitions the algorithm have the following result: \{5, 14, 15\}.
  Finally the algorithm check purity of families and shift them form $F_{7}'$ to $F_7$.

  Finally PS-table has the following view:

  \begin{figure}[h]
	  {\footnotesize\noindent
		\begin{tabular}{|c|c|c|c|c|c|c|c|} \hline
	 	& $\slpterm{F}{1}{a}$ & $\slpterm{F}{2}{b}$ & $\slpnonterm{F}{3}{1}{2}$ & $\slpnonterm{F}{4}{3}{1}$ &
	 	$\slpnonterm{F}{5}{4}{3}$ & $\slpnonterm{F}{6}{5}{4}$ & $\slpnonterm{F}{7}{6}{5}$ \\ \hline

	 	[1, 1] & $\varnothing$ & $\varnothing$ & $\varnothing$ & $\varnothing$ & \{1, 3, 3\} & $\varnothing$ & \{1, 8, 8\} \\
	 	\hline

	 	[2, 3] & $\varnothing$ & $\varnothing$ & $\varnothing$ & $\varnothing$ & $\varnothing$ & \{3, 4, 4\}, \{2, 5, 6\} &
	 	\{3, 10, 10\} \\ \hline

	 	[4, 7] & $\varnothing$ & $\varnothing$ & $\varnothing$ & $\varnothing$ & $\varnothing$ & $\varnothing$ & \{5, 5, 6\}
	 	\\ \hline
		\end{tabular}
	  }
  \end{figure}
\end{itemize}

\subsection{Text with complex family of pure squares}
Let us consider an SLP $\slp{E} = \slp{E}_l \cdot \slp{E}_r$ such that $\slp{E}_l$ derives text $(a~b~a~b~a)^6~a~b~a$
and $\slp{E}_r$ derives text $b~a~a~b~a~(a~b~a~b~a)^7$. So $\slp{E}$ derives text $(a~b~a~b~a)^7~a~b~a~(a~b~a~b~a)^7$
and $|E| = 73$. Let us consider how the algorithm looking for pure squares for rule $\slp{E}$ and segment [16, 31]. The
algorithm construct SLP $\slp{E}'$ that surrounds with \emph{\$} and has length 128. The partition of $E'$ into blocks
presented at figure 9.

\ComplexExamplePartititon

Let us consider how the algorithm process block $B_8$. It find occurrence of $B_8$ in $B_9 \cdot B_{10}$ at positions
$\prog{72}{2}{5}$. Since the algorithm find more than one occurrence it extends periodicity to calculate parameters
$\alpha_L, \alpha_R, \gamma_L, \gamma_R$. So $\alpha_L = \infty, \alpha_R = 69, \gamma_L = 66, \gamma_R = \infty$.
According to lemma !!! the algorithm find complex family of pure squares associated with each of root length \{18, 23\}
and centred at positions \{66, 67, 68, 69\}. Next we write every root from the family exactly:

\begin{itemize}
  \item \textbf{roots of length 18}

  $a~b~a(a~b~a~b~a)^3$, $b~a(a~b~a~b~a)^3a$, $a(a~b~a~b~a)^3a~b$, $(a~b~a~b~a)^3a~b~a$;
  \item \textbf{roots of length 23}

  $a~b~a(a~b~a~b~a)^4$, $b~a(a~b~a~b~a)^4a$, $a(a~b~a~b~a)^4a~b$, $(a~b~a~b~a)^4a~b~a$;
\end{itemize}

\end{appendix}

\end{document}


\section{Algorithms}

\subsection{B and B+ Algorithms}
% kenny, put a section here about B+ algorithms
The theory for the implementation was deceptively simple, since we had
worked it out on paper in class, and the algorithms were simple enough
to read through.  However general human intuition turned out to be
fairly complicated to translate into usable Javascript code.  In order
of complexity of implementation we had the general tree and node
object structue, then the search methods, followed distantly by the
insertion and deletion methods, which turned out to be quite complex
to implement appropriately.

Setting up the general structure for the objects that would represent
our trees and the nodes that make them up was simple enough.  For B
trees we created an object with properties to hold a master list of
all nodes in the tree, the order of the tree, a direct reference to
the tree's root node, a counter forthe number of nodes in the tree,
and references to the methods for searching, insertion, and deletion
methods, as well as a helper method called \texttt{insertUp}, which is
called recursively after a node overflows to handle splitting the node
and inserting the appropriate key into the parent node.  For B+ trees,
the object we created has almost all the same properties, but its
\texttt{insertUp} method is only for internal node overflow handling,
and it also has a reference to a method called
\texttt{bp\_leaf\_split} which handles overflow in a leaf node.

The node objects we created were designed to be used for both tree
structures.  They contain a list of the values/keys in the node, a
list of the children to the node, a reference to the node's parent,
counters for the number of values/keys and for the number of children,
a flag to signify if the node is a leaf node, and a reference to a
helper method that returns the list of children to the node.

Inside our tree objects, we maintain a list of all the nodes in the
tree. This is necessary because Javascript does not have pointers as
seen in languages such as C. In order to implement the tree, we needed
to simulate pointers. Our solution is to maintain an array to which we
store all our nodes. The indices of this array serve as the equivalent
of pointer references for our tree. This method has the same memory
footprint as a method that would have used pointers, though it adds a
few extra lines of code where we have to constantly reference back to
the trees node list and look up the index value of whatever node we
want to reference.

Implementing search for the two tree types was fairly straight forward
and was accomplished in as few as 27 lines of code.  For B trees, the
method for searching consists of starting at the root, inspecting in
the search value is in the node, if not then we decide which child
node it would be in and then recursively call the search function
starting from the child node the value should be in.  If we encounter
a dead end and have not yet found our value, then we return that the
value did not exist in the tree.  If we do find the value we return
the index of the node it was found in and a true flag to indicate that
the value was found.  The method for searching a B+ tree was similar
except we do not check to see if the search value is in the current
node until we've reached a leaf node.  Until we reach a leaf we just
decide which child to explore next and recursively call the search
function starting from that child.  Once we've reached a leaf node, if
we find the value in the node, we return the node index amd a true
flag.  If we reach a leaf node, and it does not contain our search
value, then we return falseto indicate the value does not exist in the
tree.

Implementing insertion into the trees was where things became a bit
complicated.  Specifically having to handle overflow and node
splitting.  The insertion mothed for B trees starts out fairly simple,
we do a search through the tree for the insertion value.  Regardless
of whether the value is found or not, the search method should return
us the node that the value should be inserted into.  We then do a
brute force insert into the node, temporarily ignoring order, just to
get the nodes values sorted.  Once we have the value inserted, we
check if the node is now overflowing or not, if not we are done and
end the function.  If we do encounter overflow then we quickly
calculate the median value and partition the values into two separate
sets around the median, but neither including the median value.  We
then pass the two sets of values, the median value, the index of the
median value, and the current node to out \texttt{insertUp} method to
handle the spliting of the node.  The \texttt{insertUp} method
recieves these values and that check to see if the current node is the
root node or not.  If we are splitting the root node then the split is
easy enough to accomplish.  We create two new nodes that will become
the children to the root, and each inherit half the children of the
previous root.  We want to keep the root of the tree at index 0 in the
array of all nodes in the tree for convenience, which is why the new
nodes created are the children to our new root, and not one of the
children and the new root node.  We assign the appropriate values and
children to the new nodes, and set them to look at the root node as
their parent, we then assign the the new root the median value from
the split node, and set its children to include the new children nodes
we have created.

If the node to be split was instead a leaf or internal node then the
method of splitting is slightly different.  In this case we are only
creating one new node to the tree, all the appropriate values and
children, if any exist, are split between the original node we are
splitting and the new node we are creating to take in half the values,
and possible half the children.  We then recursively call the
\texttt{insertUp} method to insert the median value into the split
node's parent.  The function will recurse until either no node needs
to be split, or we've split the root node.

Insertion for B+ trees in almost identical, except it has to handle an
extra specific case that B trees do not deal with.  Splitting internal
nodes and the root node function identically, but B+ trees behave
differently than B trees when splitting leaf nodes, and so an extra
method to handle this case called \texttt{bp\_leaf\_split} is
implemented.  When splitting a leaf node, it is similar to splitting
an internal node, with slight changes.  When splitting a leaf node, we
split the node down the middle, but do not separate out the median
value to be inserted up into the parent node.  Instead, we select the
smallest value from the right side of the split node and insert that
as a key into the parent node, this being because all values are
stored at the leaf level in B+ trees.  After splitting a leaf node we
then call the B+ tree's insertUp method to handle insertion of the new
key and potential splitting of the parent node.

After some tweaking and discussion about our implementation for
deletion in both B and B+ trees, we made the decision to change from
our original intended method in exchange for a more streamlined,
though more costly method.  In investigating methods for implementing
deletion from B and B+ trees we found there to be two popular methods
of accomplishing this task.  The first is the most obvious, but also
the more complex of the two to implement.  It consists of search for
the value in the tree, removing it from where it lies, and then if the
node should underflow, borrow from or merge with sibling nodes, and if
need be change keys in parent nodes, which could then result in
underflow propagating upward in the tree, which in turn would need to
be handled.  The other method suggested passing through the tree and
restructuring it such that no underflow would occur when the value is
removed.  We had originally intended to implement the first method,
but found that in development that the way we had things structured
made it mush easier to implement the second method.  Our
implementation of this method was fairly straight forward. First, we search
for the value to be deleted. If we find it and no underflow will
occur, we remove it and are done.  If underflow does occur, then
utilizing the tree's master list of values in the tree, we reconstruct
the tree from these values, less the deleted value.  Our
implementation run approximately in time $O(n \text{\,log\,} n)$, but for small n
the effect on performance in negligible.

\subsection{Graph Layout Algorithms}
The UI portion of this project requires a sizable amount of
algorithmic work. The most difficult factor is the development of a
node layout algorithm that prevents node overlap, while also giving an
ideal spacing between the nodes in the tree. This is especially
important as the size of the tree grows.

A popular method for solving this problem is the use of the
force-based algorithm. This algorithm works well for spreading nodes
out over 2 or 3 dimensional space. However, it does not take into
account the movement limitations that are imposed in a B+
tree. Namely, the nodes in a B+ tree can only move horizontally except
for in the case of a node split or join.

A secondary issue with the use of force-based algorithms is that they
have a running time of O$(n^3)$. This long running time is not ideal
for large trees. Our design helps mitigate the issues presented by
this running time. Namely, the size of the tree that can be visible to
the user is limited by the available screen real estate. This limits
the number of nodes down to a reasonable level, and thus keeps our
running time within reason.

Force based algorithms operate by modeling interaction between the
graph nodes using equations borrowed from physics. Each node is
treated as an electrically charged particle, repelling the other nodes
in the graph according to Coulomb's Law. Each edge on the graph is
treated as a spring, attracting the two connected nodes according to
Hooke's Law. The simulation randomizes initial node positions and then
simulates each time step in the model until equilibrium is reached. At
equilibrium, the nodes should be placed in such a way that overlap is
minimized.

%% what we did
Adapting this algorithm to work with our constraints proved to be an
interesting challenge. Of primary concern was the limitation that each
node should stay on its own level in the tree throughout the
simulation. This problem turned to be simple to solve. We modified the
initial force-based algorithm so that nodes could only apply force on
the X coordinate plane.

After implementing this system, it became clear that there were still
some serious issues to address. The nodes in the tree were becoming
far to spread apart. Furthermore, they were also off-center from their
expected locations. After some experimentation, it was determined that
the issue sprouted from an assumption the original algorithm made. The
original algorithm assumed that all nodes would repel each-other, as
would make sense in a 2-dimensional model. Unfortunately, the same
rule did not apply for 1-dimensional models. The solution to this
problem was to modify the code in such a way that the nodes in the
model would only repel against other nodes on that level of the tree.

The next issue encountered was that of node ordering. In the
standard force-based algorithm, all edge endpoints for a given node
have the same $(x,y)$ coordinates, and ordering does not matter. In
the case of B and B+ Trees, this is not true. Not only does each node
have multiple edge endpoints, but ordering also is extremely
important.

The endpoint problem was trivially solved by simply adjusting our
$(x,y)$ coordinates for the parent node. The issue of ordering proved
to be a bit more difficult. The solution we designed relies on the
algorithm used to build the tree. This algorithm inserts nodes one at
a time in a left to right order. With this in mind, our force-based
algorithm inserts all new nodes at the proper level, but to the far
right of the graph. This causes all of the nodes to shift to the left
as the model reaches equilibrium. Because the nodes should not cross
each other on the x-axis, they should maintain the same ordering throughout.
%% WIP

\subsection{Example of Tree Construction}

\begin{figure}[htp!]
\centering
\includegraphics[scale=0.25]{images/Insert_one.png}
\caption{B tree after inserting value 1}
\label{EX1}
\end{figure}

\begin{figure}[htp!]
\centering
\includegraphics[scale=0.25]{images/Insert_two.png}
\caption{B tree after inserting value 2}
\label{EX2}
\end{figure}

\begin{figure}[htp!]
\centering
\includegraphics[scale=0.25]{images/Insert_three_split_root.png}
\caption{B tree after inserting value 3, splitting root}
\label{EX3}
\end{figure}

\begin{figure}[htp!]
\centering
\includegraphics[scale=0.25]{images/Insert_four.png}
\caption{B tree after inserting value 4}
\label{EX4}
\end{figure}
\clearpage

\begin{figure}[htp!]
\centering
\includegraphics[scale=0.25]{images/Insert_zero.png}
\caption{B tree after inserting value 0}
\label{EX5}
\end{figure}


% OUTLINE:
% * Introduction: a bright comet is coming!
% * Observations: COBS, criteria.
% * Light curve analysis: model, model fitting.
% * Discussion & caveats:
%   - compare surface brightness to stars

\documentclass[RNAAS]{aastex63}

%% Define new commands here
\newcommand\latex{La\TeX}
\graphicspath{{./}{figures/}}
\begin{document}

\title{A Probabilistic Brightness Prediction for Comet C/2019 Y4 (ATLAS)}

\correspondingauthor{Geert Barentsen}
\email{hello@geert.io}

\author[0000-0002-3306-3484]{Geert Barentsen}
\affiliation{Bay Area Environmental Research Institute, P.O. Box 25, Moffett Field, CA 94035, USA}

\keywords{Long period comets}

\section{Introduction} \label{sec:intro}

Several media outlets recently reported that comet C/2019 Y4 may soon provide a spectacular \textit{Great Comet} display.
The object was originally discovered on 2019 Dec 28 at magnitude $V\approx19.5$ \citep{CBET4712}. The comet's brightness increased rapidly thereafter, reaching $V\approx8$ by late March (Fig.~\ref{fig:1}).
The comet is expected to reach peak brightness near its perihelion date on 2020 May 31.
In this research note, we estimate the comet's brightness evolution in a probabilistic way by combining citizen science observations with prior information from previous comets.

\begin{figure}[h!]
\begin{center}
\includegraphics[scale=0.85,angle=0]{2019y4-prediction.pdf}
\caption{Light curve of comet C/2019 Y4. Plusses and crosses show visual and CCD observations from the COBS database. The mean model fit is shown as a thick dashed line. Thin black lines show random MCMC draws to visualize the model uncertainty. The grey hatched area indicates when the comet will be within 20 degrees from the Sun as seen from Earth.\label{fig:1}}
\end{center}
\end{figure}

\section{Observations}

The
\textit{\href{https://cobs.si}{Comet Observation Database}} \citep[COBS;][]{2018JBAA..128..279Z} contains nearly 250,000 brightness estimates of 1285 comets dating back to 1884. The data are predominantly contributed by citizen scientists.
At the time of writing, the database contained 354 observations of C/2019 Y4 contributed by 52 volunteers across 18 countries.
Fig.~\ref{fig:1} shows the subset of 296 good-quality observations that met the selection criteria\footnote{We use observations reported with the COBS method codes S, B, M, I, E, Z, V, or O. Observations flagged as ``poor'' or ``upper limit'' are excluded.} for our analysis.

\section{Light curve analysis}

The canonical method to model the total magnitude $m$ of a comet (integrated across the coma) as a function of the body's geocentric and heliocentric distances ($\Delta$ and $r$) is a power-law formula in the form
\begin{equation}
m = H + 5 \log{\Delta} + 2.5\,n\,\log{r},
\end{equation}
where $H$ is the absolute magnitude, and $n$ is the \textit{activity index} which is a proxy for the rate of dust production as a function of heliocentric distance. The typical value for $n$ is 4 \citep[][]{2001A&G....42a..11G}, but values exceeding $n>8$ have been reported for segments of light curves associated with enhanced activity \citep[e.g.][]{1990acm..proc..327H}.

We use \texttt{\href{https://docs.pymc.io}{PyMC3}} \citep{pymc} to fit the power law model to the observations in a probabilistic way.
We model the residuals using a zero-centered Cauchy distribution with scale parameter $\beta$.
We adopt empirical Gaussian priors $\beta \sim \mathcal{N}(\mu=0.47,\,\sigma=0.02)\,$,
$n \sim \mathcal{N}(3.5,\,1.4)\,$,
and
$H \sim \mathcal{N}(6.7,\,2.0)\,$.
We derived these priors by fitting the same model to the 12 brightest long-period comets available in the COBS database.
Finally, we sample the model posterior using the default Markov Chain Monte Carlo algorithm provided by \texttt{PyMC3}.  We verified that changing the priors does not significantly alter the posterior.

\section{Results}

The model light curve corresponding to the mean posterior parameters is shown as a dashed line in Fig.~\ref{fig:1}.
We find a mean value of $n=4.5\pm0.5$ for the activity index, and $H=5.9\pm0.3$ for the absolute magnitude. This corresponds to a peak brightness $m=-1\pm1$ on 2020 May 31.

\section{Discussion}

Given the current observations and the canonical light curve model, C/2019 Y4 is on track to become the brightest comet since C/2011 W3 (Lovejoy).
We caution the reader for three important caveats however:
\begin{enumerate}
\item The comet will be located very close to the Sun in the sky on 2020 May 31 ($13^o$ elongation). This will severely hinder the comet's visibility.
The observing conditions will be more favorable on or before 2020 May 20 ($24^o$ elongation), but the comet is expected to be much fainter on that date ($m=+1\pm1$).
\item We find that the early observations of the comet prior to mid-March do not fit the canonical model well, suggesting that the activity has decreased over time.
This indicates that the comet's surface may have been covered by a thin layer of volatile materials which have now been depleted. If we exclude the outlier observations recorded prior to 2020 March 15 from the model fit, the expected peak brightness drops significantly to $m=+5\pm1$.
\item Finally, we caution that comets are notoriously difficult to predict.
For example, we cannot exclude the possibility that C/2019 Y4 may break into fragments and brighten dramatically, or conversely, the object may lose its volatiles and fade away more quickly than expected.
\end{enumerate}

%The coma brightness is likely to be spread out across several arcminutes however, likely making the comet look fainter to the eye than a star of a similar brightness.

%In summary, given the current observations and a canonical light curve model, we do not currently expect comet C/2019 Y4 to appear as a \textit{Great Comet}.

The code used in this analysis is available as generic Python package called \texttt{cometcurve} available at \url{github.com/barentsen/cometcurve}. The reader can use this tool to keep track of the comet's evolution.

%The parameter $n$ is able to fit the light curves of many comets in a statistical sense. It is insufficient to capture intricate details in the light curves of comets, which are known to show variability (e.g. cite).

\acknowledgments

The COBS database is the product of the volunteer observers and database maintainers.
The data is available under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
% obs = cc.read_cobs(comet="2019Y4", allowed_methods='all')
% ", ".join(obs.observer_name.value_counts().keys())
Specifically, this analysis depends on observations contributed by
Thomas Lehmann, Artyom Novichonok, Denis Buczynski, Steffen Fritsche, Christian Harder, Carl Hergenrother, Piotr Guzik, Maik Meyer, Maciej Kwinta, Nick James, Alex Scholten, Jerzy Bohusz, Johan Warell, David Swan, Mike Collins, Maciej Reszelski, Gerhard Scheerle, Jacek Powichrowski, Martin Masek, Tomasz Sciezor, Gideon van Buitenen, Sandor Szabo, Timo Karhula, Robin Hegenbarth, Nirmal Paul, Marek Biely, Harri Kiiskinen, Piotr Nowak, Andreas Kammerer, Kevin Hills, Volker Kasten, Marcin Filipek, Walter Kutschera, Pavol Dubovsky, Juan Jose Gonzalez Suarez, Jakub Cerny, Pedro Pérez Corujo, Peter De Schrijver, Kristof Friedrich, Teerasak Thaluang, Uwe Pilz, Adam Tuznik, Jose Pablo Navarro Pina, Mikolaj Sabat, Salvador Aguirre, Vladimir Bespalov, Miroslav Lostak, Seiichi Yoshida, Mariusz Swietnicki, Carlos Labordena, Michael Linnolt, and Tibor Csorgei.

\begin{thebibliography}{}

\bibitem[Green et al.(2001)]{2001A&G....42a..11G} Green, D.~W.~E., Marsden, B.~G., \& Morris, C.~S.\ 2001, Astronomy and Geophysics, 42, 1.11

\bibitem[Green(2019)]{CBET4712} Green, D.~W.~E.\ 2019, Central Bureau Electronic Telegrams 4712

\bibitem[Hughes(1990)]{1990acm..proc..327H} Hughes, D.~W.\ 1990, Asteroids, Comets, Meteors III, 327

\bibitem[Salvatier et al.(2016)]{pymc}
Salvatier, J., Wiecki, T.~V., Fonnesbeck, C.\ 2016, PeerJ Computer Science, 2, e55

\bibitem[Tonry et al.(2018)]{2018PASP..130f4505T} Tonry, J.~L., Denneau, L., Heinze, A.~N., et al.\ 2018, \pasp, 130, 064505

\bibitem[Zakrajsek \& Mikuz(2018)]{2018JBAA..128..279Z} Zakrajsek, J., \& Mikuz, H.\ 2018, Journal of the British Astronomical Association, 128, 279

\end{thebibliography}

\end{document}


% !TEX root = ../zeth-protocol-specification.tex

\chapter{Instantiation of the cryptographic primitives}\label{chap:instantiation}

In this chapter, we start by instantiating the cryptographic building blocks used in previous sections to describe the \zeth~\dapscheme~design. Finally, we proceed by providing security proofs justifying that our instantiation complies with the security requirements listed in previous sections.

Note that, in several cases, it is necessary to specify details in terms of concrete properties of the curve \Curve~and associated scalar field $\FFx{\rCURVE}$. In these cases, we focus on two curves of interest: \BNCurve~and \BLSCurve. We note, however, that other suitable curves could be used.

\BNCurve~\cite{bn-prime} has several properties that make it implementation-friendly. Elements of both the base field and scalar field can be represented in \ethWordLen~bits (the native word size of the \evm), allowing efficient encoding and manipulation of such elements. Moreover, a subset of operations on \BNCurve are supported by the \evm~through precompiled contracts. These precompiled contracts enable verification of signatures (\cref{instantiation:otsig}) and zero-knowledge proofs (\cref{instantiation:zksnark}), required by this protocol, with minimal gas overhead.

\BLSCurve~\cite{bowe18zexe}, like \BNCurve, has the advantage that scalar field elements can be represented within \ethWordLen-bit words (although the same is not true of base field elements). However, the \evm~provides no native support for \BLSCurve, which increases the complexity of the \mixer~implementation (see \cref{zeth-protocol:process-tx}~for details of the operations to be performed). An advantage that \BLSCurve does provide, is that is it the ``inner'' curve of a one-layer chain (as described in \cite{bowe18zexe,housni2020onelayer}). Therefore zero-knowledge proofs using \BLSCurve can be efficiently verified by statements in other zero-knowledge proofs using an approporiate ``outer'' pairing. Support for \BLSCurve in \zeth~therefore admits several applications (no explicitly covered by this document), such as aggregation of proofs over multiple \zeth~transactions (e.g.~\cite{rondelet2020zecale}).

Further details related to implementation and optimization are given in \cref{chap:implementation}.

\input{./chapters/chap03-sec01.tex} % PRFs, COMM and CRHs (may need to be split if we decide to instantiate these with different functions)
\input{./chapters/chap03-sec02.tex} % MKHASH
\input{./chapters/chap03-sec03.tex} % Zeth statement after instantiation
\input{./chapters/chap03-sec04.tex} % OT-SIG
\input{./chapters/chap03-sec05.tex} % Encryption scheme
\input{./chapters/chap03-sec06.tex} % ZkSNARK