\chapter{Additional Features}
Various features of {\ViennaMath}, which are not necessarily standard features of a symbolic math library, are covered in this chapter.
Additional feature requests should be sent to
\begin{center}
\texttt{viennamath-support$@$lists.sourceforge.net}
\end{center}

  \section{\LaTeX{} Output}
Since {\ViennaMath} encourages a high-level description and manipulation of the underlying mathematical problem formulation in source code, it is natural to
generate \LaTeX{} code from {\ViennaMath} expressions for debugging purposes. The generated code can be copy\&paste'd to LaTeX rendering webpages or used for
the automatic generation of program log files in the form of a \LaTeX{} document.

All conversion is carried out by a separate converter object of type \lstinline|rt_latex_translator<InterfaceType>| as defined in
\lstinline|viennamath/manipulation/latex.hpp|. A convenience shortcut \lstinline|latex_translator| is available for the default runtime expression interface.
Conversion is triggered by providing the expression to be converted to the functor:
\begin{lstlisting}
 latex_translator  to_latex;

 expr f = sqrt( x + y );
 to_latex( f );     //returns the string '\sqrt{x_{0}+x_{1}}'
\end{lstlisting}
By default, variables are printed as $x_0$, $x_1$, etc. This and other output routines can be customized by using the \lstinline|customize()| member function
of the converter. For example, to print 'x' and 'y' instead of 'x\_\{0\}' and 'x\_\{1\}', the code
\begin{lstlisting}
 to_latex.customize(x, "x");
 to_latex.customize(y, "y");
\end{lstlisting}
is sufficient. Similar customizations can be applied for the output of types and features described in the remainder of this chapter.

\NOTE{The \LaTeX{} generator works with runtime expression types only. Thus, compiletime expression types need to be converted to runtime expression types
first.}

  \section{Differential Operators}
For enabling dimension-independent programming, dimension-independent mathematical differential operations are also provided with {\ViennaMath}.
In {\ViennaMathversion}, the gradient and the divergence operators are provided by the functions \lstinline|grad()| and \lstinline|div()| respectively:
\begin{lstlisting}
 expr u = grad(x+y);
 expr v = grad(x-y);
 expr w = div(grad(x*x + y*y));
\end{lstlisting}
Note that expression containing differential operators cannot be evaluated directly, since a coordinate system needs to be specified first.

A coordinate system is applied to the previous expressions by using the free function \lstinline|apply_coordinate_system()|, which is defined in the header file \lstinline|viennamath/manipulation/apply_coordinate_system.hpp|. The first function argument is a tag identifying the coordinate system (either of type \lstinline|cartesian<1>|, \lstinline|cartesian<2>|, or \lstinline|cartesian<3>| for a Cartesian coordinate system in one, two or three dimensions). The second function argument is the expression to which the coordinate system should be applied:
\begin{lstlisting}
 apply_coordinate_system(cartesian<1>(), u); //returns 1 + y
 apply_coordinate_system(cartesian<2>(), v); //returns (1, -1)
 apply_coordinate_system(cartesian<3>(), w); //returns 4
\end{lstlisting}
Differential operators are very handy in combination with function symbols explained in Sec.~\ref{sec:function-symbols}.

%%%%%%%%%%%%%%%
  \section{Integration Symbols}
In certain cases the form of an integral expression is known, but the actual integration domain is determined at some later stage.
Here, a symbolic integration domain of type \lstinline|symbolic_interval| identified by an ID can be specified and substituted by the final integration interval later on.
For example, the integral $\int_\Omega x^2 \: \mathrm{d} \Omega$, where $\Omega$ is specified at some later point, is specified using {\ViennaMath} as
\begin{lstlisting}
 expr my_integral = integral(symbolic_interval(), x*x);
\end{lstlisting}
The interface is again such that it can be used with both runtime and compiletime types. For simplicity, the resulting integral expression is here assigned to a runtime expression \lstinline|my_integral|. An ID can be provided to the constructor of \lstinline|symbolic_interval| for distinguishing between different symbolic intervals. By default, an ID of $0$ is used.

In order to substitute the symbolic interval with the actual integration interval, the function \lstinline|substitute()| as explained in Sec.~\ref{sec:substitute} is used.
Since the replacement consists of both the integration interval and the variable over which integration is to be carried out, the replacement argument is packed into a \lstinline|pair| as defined in the C++ STL. Thus, in order to specify $\Omega$ as the interval $[0,1]$ with an integration over the $x$-variable, the code
\begin{lstlisting}
 expr my_integral2 = substitute( symbolic_interval(),
                                 std::make_pair(interval(0, 1), x),
                                 my_integral);
\end{lstlisting}
is sufficient. Note that in the current release of {\ViennaMath} only the substitution with a one-dimensional integration domain is supported, but no nested integrals are possible yet.

\TIP{Note that \lstinline|std::make_pair()| is defined in the header \lstinline|<utility>|.}

%%%%%%%%%%%%%%%
  \section{Function Symbols} \label{sec:function-symbols}
For discretization schemes based on weak formulations of partial differential equations it is appropriate to work with abstract functions rather than with concrete expressions.
For example, the weak form of the Poisson equation,
\begin{align} \label{eq:weak-poisson}
 \int_\Omega \nabla u \cdot \nabla v \: \mathrm{d} x = \int_\Omega fv \: \mathrm{d} x
\end{align}
for all test functions in a certain test space $\mathcal{V}$, is formulated for functions $u$ and $v$, which are during the discretization replaced by certain trial and test functions, which finally yields a system of linear equations.
Such function labels (\emph{function symbols}) are modeled in {\ViennaMath} by the type \lstinline|rt_function_symbol<InterfaceType>| at runtime (with convenience shortcut \lstinline|function_symbol| for the default runtime interface type) and by \lstinline|ct_function_symbol<T>| at compiletime, where \lstinline|T| is a tag identifying the function symbol.

As a simple example, the expression $uv$ is considered, where $u$ is then substituted with the expression $(1+x)$ and $v$ is replaced by $(1-x)$:
\begin{lstlisting}
 function_symbol u(0);
 function_symbol v(1);
 expr f = u * v;
 expr g = substitute(u, 1.0 + x,
                     substitute(v, 1.0 - x, f)
                    );    // g becomes (1+x)*(1-x)
\end{lstlisting}
The constructor arguments denote the function symbol ID used for distinguishing the individual function symbols.

Reconsidering the weak form \eqref{eq:weak-poisson}, function symbols at compiletime can use any arbitrary tag class for identification.
{\ViennaMath} provides the predefined tags \lstinline|unknown_tag<id>| and \lstinline|test_tag<id>|, where the integer template parameter \lstinline|tag| is used for distinguishing between several function symbols of the same tag. The previous code snippet rewritten for compiletime manipulation thus becomes
\begin{lstlisting}
 ct_function_symbol< unknown_tag<0> > u;
 ct_function_symbol<    test_tag<0> > v;
 substitute(u, 1.0 + x,
            substitute(v, 1.0 - x, u*v)
           );    // returns (1+x)*(1-x)
\end{lstlisting}
Note that the result type of \lstinline|substitute()| encodes the result \lstinline|(1+x)*(1-x)|, thus the result is usually directly passed to another function (e.g.~\lstinline|eval()|) in order to avoid writing the return type explicitly.

As a final example, the weak form \eqref{eq:weak-poisson} (with $f \equiv 1$ for simplicity) is specified directly as a {\ViennaMath} runtime expression and converted to {\LaTeX}-code using the functionality presented in this chapter:
\begin{lstlisting}
 function_symbol u(0);
 function_symbol v(1);
 equation weak_form = make_equation( integral( symbolic_interval(),
                                               grad(u) * grad(v) ),
                                     integral( symbolic_interval(), v ) );
 latex_translator to_latex;
 std::cout << to_latex(weak_form) << std::endl;
\end{lstlisting}

\TIP{ Have a look at \texttt{ViennaFEM}~(\texttt{http://viennafem.sourceforge.net/}) if you are interested in a software package using {\ViennaMath} for the finite element method. }


\chapter{Introduction}
\label{chapter:introduction}
\par
The Lanczos eigensolver
finds selected eigenvalues and eigenvectors of
% three types of eigenproblems,
$AX = B X \Lambda$, where $X$ are eigenvectors
and $\Lambda$ is a diagonal matrix whose elements are eigenvalues.
Three types of eigenproblems are supported.
\begin{itemize}
\item
An ``ordinary'' eigenvalue problem
where $A$ is symmetric and $B = I$.
\item
An ``vibration'' eigenvalue problem
where $A$ is symmetric and
$B$ is symmetric positive semidefinite.
\item
A ``buckling'' eigenvalue problem
$A$ is symmetric positive semidefinite and
$B$ is symmetric.
\end{itemize}
For the vibration and buckling problems, there must exist a
$\sigma$ that is not an eigenvalue such that
$A - \sigma B$ is nonsingular,
i.e., $A$ and $B$ cannot share the same null space.
\par
During the computations, the eigensolver requires the following
sparse linear algebra computations.
\begin{itemize}
\item
Sparse factorizations of the form $A - \sigma B$.
\item
Solves of the form $(A - \sigma B) Z = Y$.
\item
Multiplies of the form $Z = B Y$ (for the vibration problem)
or $Z = A Y$ (for the buckling problem).
\end{itemize}
The Lanczos eigensolver has defined a specific interface with an
external linear algebra package to perform these three operations.
The eigensolver currently interfaces with the {\bf BCSLIB-EXT} linear
solver in a serial environment and the {\bf SPOOLES} linear solver
in serial, multithreaded and MPI environments.
\par
This paper documents the {\bf SPOOLES} objects and functions
that interface with the eigensolver.
The three following chapters describe the serial, multithreaded and
MPI objects, their data structures, and their methods.
The appendix contains listings of three driver programs to exercise
the eigensolver using the {\bf SPOOLES} library.
\par
Symmetric permutations of the eigensystem do not change the
eigenvalues, and the eigenvectors can be easily constructed
using the permutation matrix.
$$
A X = B X \Lambda
\longrightarrow
{\widehat A} {\widehat X}
= {\widehat B} {\widehat X} \Lambda
\quad \mbox{where} \quad
{\widehat A} = PAP^T, \quad
{\widehat B} = PBP^T, \quad
\mbox{and} \quad
{\widehat X} = PX
$$
The linear algebra package is free to use any permutation matrix
$P$ to most efficiently perform the factorizations and solves
involving ${\widehat A}$ and ${\widehat B}$.
This permutation matrix $P$ is typically found by ordering the
graph of $A + B$ using a variant of minimum degree or nested
dissection.
The ordering is performed prior to any action by the eigensolver.
This ``setup phase'' includes more than just finding the
permutation matrix, e.g., various data structures must be
initialized.
In a parallel environment, there is even more setup work to do,
analyzing the factorization and solves and specifying which threads
or processors perform what computations and store what data.
In a distributed environment, the entries of $A$ and $B$ must
also be distributed among the processors in preparation for
the factors and multiplies.
\par
For each of the three environments --- serial, multithreaded and
MPI --- the {\bf SPOOLES} solver has constructed a ``bridge''
object to span the interface between the linear system solver
and the eigensolver.
Each of the {\tt Bridge}, {\tt BridgeMT} and {\tt BridgeMPI}
objects have five methods: set-up, factor, solve, matrix-multiply
and cleanup.
The factor, solve and matrix-multiply methods follow the calling
sequence convention imposed by the eigensolver, and are passed
to the eigensolver at the beginning of the Lanczos run.
The set-up method is called prior to the eigensolver, and the
cleanup method is called after the eigenvalues and eigenvectors
have been determined.


\section{Statements}\label{sec:statements}
Statements are defined as constructs that have the possibility to change the state of the program. The state of the program is defined as the symbol by which values are associated. We call this the environment and it is formally described as:
\begin{center}
$e = \text{Symbols} \rightharpoonup \text{Stm} \times \text{Symbols}$
\end{center}
This is a partial function that maps symbols to statements and other statements. These statements are the statements that are run when the symbol is invoked. If these map to an expression, the invocation takes the value of that invocation in the current environment. This can be any expression and, as previously explained ,the symbol evaluates to whatever the expression maps to. Note that a block is also an expression, see \cref{subsubsec:invocation}. If the statements evaluate only to a statement, the symbol is of type \enquote{unit} and it has no value. Note that the statements can still update the state of the program during the invocation.

If the symbol takes input arguments, these are placed inside the \enquote{Symbols} on the right hand side of the arrow. In an invocation these symbols will be mapped to the values given as input parameters.

\input{Design/Statements/valueAssignment.tex}
\input{Design/Statements/structures.tex}
\input{Design/Statements/forLoopStatements.tex}
\input{Design/Statements/whileStatements.tex}
\input{Design/Statements/conditional.tex}
\input{Design/Statements/composition.tex}


\subsection{Homework}
\begin{enumerate}
\item Search the internet for equations containing a Laplace operator
  and models from science, economics, etc.
\item Energy minimization and weak formulation
\item Prove Poincare inequality (1D)
\end{enumerate}

\subsection{Classroom topics}
\begin{enumerate}
\item Model problem: Poisson equation, boundary conditions
\item Lack of solution theory
\item Weak formulation, natural boundary condition, analogy to linear algebra
\item Elementary integration
\item Elementary Sobolev spaces, Lax-Milgram
\end{enumerate}

%%% Local Variables:
%%% mode: latex
%%% TeX-master: "main"
%%% End:


\documentclass[11pt]{article}
\setcounter{secnumdepth}{0}

\usepackage{relsize}

\newcommand{\mono}[1]{{\smaller\texttt{#1}}}                    % literal (to be typed): code, program names

\begin{document}

\section{Fitting a mixture Dirichlet to counts}

\mono{esl\_mixdchlet\_Fit()} infers a maximum likelihood mixture
Dirichlet distribution for a data set of count vectors. It uses
conjugate gradient descent from an initial starting point. The result
is only a local optimum, so we typically run it multiple times with
different starting points. The partial derivatives of the log
likelihood function are persnickety, and the purpose of these notes is
to enshrine the derivation that corresponds to the implementation.

We have $N$ count vectors $c_i$, with each vector consisting of $K$
counts for individual symbols $c_{ia} \geq 0$. The mixture Dirichlet
$\theta$ consists of $Q$ components $\alpha_k$, with each parameter
vector containing $K$ parameters $\alpha_{ka} > 0$, and $Q$ mixture
coefficients $q_k > 0, \sum_k q_k = 1$.

The log likelihood of the data is:

\[
  L = \log P(\mbox{data} \mid \theta) = \sum_i \log P(c_i \mid \theta) = \sum_i \log \sum_k q_k P(c_i \mid \alpha_k)
\]

\mono{esl\_mixdchlet\_logpdf\_c()} calculates $\log P(c_i \mid
\theta)$.

$P(c_i \mid \alpha_k)$, the probability of one count vector given one
Dirichlet component, is:

\[
P(c_i \mid \alpha_k) = \frac{ |c_i|! }
                            { \prod_a c_{ia}! }
                       \frac{ \prod_a \Gamma \left( c_{ia} + \alpha_{ia} \right) }
                            { \Gamma ( |c_i + \alpha_k| ) }
                       \frac{ \Gamma ( |\alpha_k| ) }
                            { \prod_a \Gamma \left( \alpha_{ka} \right) }
\]

\mono{esl\_dirichlet\_logpdf\_c()} calculates $\log P(c_i \mid \alpha_k)$.

The conjugate gradient descent code works with unconstrained
real-valued parameters. The Dirichlet parameters $\alpha_{ka}$ are
constrained to $>0$, and mixture coefficients $q_k$ are constrained to
$>0$ and $\sum_k q_k = 1$. Define a change of variables in terms of
unconstrained parameters $\lambda_k$ for the mixture coefficients and
$\beta_{ka}$ for Dirichlet parameters:

\begin{eqnarray*}
  q_k          & = & \frac{ e^{\lambda_k} } { \sum_m e^{\lambda_m} } \\
  \alpha_{ka}  & = & e^{\beta_{ka}}
\end{eqnarray*}

After variable substitution, partial differentiation w.r.t. the
unconstrained parameters, and substituting back the original
parameters, we have for the mixture coefficients:

\[
  \frac{\partial L}{\partial \lambda_k} = \sum_i P(k \mid \theta, c_i) - q_k
\]

i.e., the difference between the posterior probability of component
$k$ $P(k \mid \theta, c_i)$, calculated by \mono{mixdchlet\_postq()},
and its prior $q_k$.

For the Dirichlet parameters:

\[
\frac{\partial L}{\partial \beta_{ka}}  =  \sum_i
 \alpha_{ka} P(k \mid \theta, c_i)
    \left( \Psi \left( c_{ia} + \alpha_{ka} \right)
        -  \Psi \left( | c_i | + | \alpha_k | \right)
        +  \Psi \left( | \alpha_k | \right)
        -  \Psi \left( \alpha_{ka} \right)
    \right)
\]

$\Psi(x)$ is the digamma function $\frac{d}{dx} \log \Gamma(x) =
\frac{\Gamma'(x)}{\Gamma(x)}$, for $x > 0$, implemented by
\mono{esl\_stats\_Psi()}.

The Easel conjugate gradient descent optimizer is a minimizer, not a
maximizer.  The implementation provides the negative log likelihood
and the negative gradient to the CG routine.

\end{document}


\documentclass[main.tex]{subfiles}
\begin{document}

\section*{3 October 2019}

Marco Peloso, \url{marco.peloso@pd.infn.it}

\section{Special relativity}

\begin{definition}
    An inertial frame is one in which Newton's laws hold: a free body moves with acceleration \(a^{i} = 0\).
\end{definition}

Newton's first law establishes the \emph{existence} of inertial frames.

\begin{proposition}
    The frames \(O\) and \(O'\) are both inertial frames iff \(O'\) moves with constant velocity wrt \(O\).
\end{proposition}

\begin{proposition}
    Coordinate transformations between inertial frames are Lorentz boosts, which in some coordinate frame can be written as
    %
    \begin{subequations}
    \begin{align}
      t' &= \gamma_v \qty(t - \frac{vx}{c^2})  \\
      x' &= \gamma_v \qty(x - vt)  \\
      y' &= y \\
      z' &= z\,,
    \end{align}
    \end{subequations}
    %
    where \(\gamma_v = 1/ \sqrt{1 - v^2 / c^2} \).
\end{proposition}

If \(v \ll c\), so \(v/c \sim 0\), they simplify to the identity for \(t\), \(y\), \(z\) and \(x' = x -vt\): these are Galilean transformations.

If we have two events, \(x^\mu\) and \(y^\mu\), they occur with some time and space separation \(\Delta x^\mu = x^\mu - y^\mu\). We can compute \(\Delta s^2 = \eta_{\mu\nu} \Delta x^\mu \Delta x^\nu \), where
%
\begin{equation}
  \eta_{\mu \nu} = \diag{-c^2, 1, 1, 1} \,.
\end{equation}

\begin{proposition}
Under Lorentz transformations \(\Delta s^2\) is invariant.
\end{proposition}

We can classify separations between events as
%
\begin{itemize}
    \item time-like when \(\Delta s^2 <0\);
    \item null-like when \(\Delta s^2 =0\);
    \item space-like when \(\Delta s^2 >0\).
\end{itemize}

We can draw spacetime diagrams. A light cone is the set of points which are null-like separated from a select point. Things can be only causally related to events inside the light-cone, with \(\Delta s^2 \leq 0\).

\subsection{Time dilation}

Take two events which occur at the same location for \(O'\). In the primed frame they will have coordinates \(x^{\mu} = (t_0, x_0)\) and \(y^\mu = (t_1, x_0)\).

\begin{definition}
    The \emph{proper time} between these two events is \(t_1 - t_0 \defeq \Delta \tau\).
\end{definition}

We now see that \(\Delta s'\,^2 = -c^2 \Delta \tau^2\). Then, any other observer will see the same  \(\Delta s^2 = - c^2 \Delta t^2 + \Delta x^2 = \Delta s'\,^2\).

This directly implies that \(\Delta \tau \leq \Delta t\) for any observer, since \(\Delta \tau^2 = \Delta t^2 - \Delta x^2 / c^2\). This effect is called \emph{time dilation}.

By how much exacly is time dilated? Of course \(\Delta x = v \Delta t\), therefore \(\Delta t = \gamma_v \Delta \tau\).

This effect explains a peculiar phenomenons: certain particles in the upper atmosphere decay into muons, which have a very short half-life. So short, in fact, that if we did not account for special relativity we'd expect to see next to none at the surface, since by the time they got here they would have alredy gone through several halving times.
However, we must apply the rule of relativistic time dilation: the muons are travelling very fast towards the ground, therefore in the ground's frame of reference their time passes slower, allowing them to decay slower.
So, a significant fraction of them arrives at the ground.

Inverse Lorentz transformation have the same expression as direct ones, but with \(v \rightarrow -v\).
This can be proved both mathematically by solving the equations and phisically by reasoning about their meaning. There is no preferential inertial frame.

A Lorentz transformation can be written in matrix form in the \((ct, x)\) plane as:

\begin{equation}
  \Lambda = \begin{bmatrix}
    \gamma & -\gamma \beta \\
    -\gamma \beta & \gamma
  \end{bmatrix}
  = \begin{bmatrix}
  \cosh \theta & -\sinh \theta \\
    -\sinh \theta &  \cosh \theta
  \end{bmatrix}
\end{equation}
%
where we introduced the notation \(\beta = v / c\).

The second equation is justified by the fact that there is an angle \(\theta\) such that \(\gamma = \cosh \theta\) and \(\gamma \beta = \sinh \theta\): the angle \(\theta\) will be \(\theta = \tanh^{-1} \qty(v/c)\).
This is true because \(\gamma^2 - \beta^2 \gamma^2 = 1\), which is the same law that the hyperbolic functions obey: \(\cosh^2 x - \sinh^2 x =1 \) holds for any \(x\).

After a boost the \(ct'\) and \(x'\) axes are rotated into, respectively, the lines \(ct=x/\beta\) and \(ct = \beta x\): this comes directly from the transformation law.
The \(ct'\) axis is defined by the equation \(x' =0\), which in the transformed coordinates \(ct\) and \(x\) reads \(\gamma (x - \beta ct) = 0\), or \(ct  = x/ \beta \).

Similarly \(ct' = 0\) in the new coordinates reads \(\gamma (ct - \beta x)=0\), or  \(ct = \beta x\).

The axes are rotated by an angle which can approach \(\pi /4\) but never reach it, since its tangent is defined by \(\beta \), which can never reach 1.

\end{document}


\subsection*{Random Number Generation \hspace*{\fill}\hyperlink{VSIPspecHead}{(up)}\hypertarget{Random}{}}\addcontentsline{toc}{subsection}{Random Number Generation}
VSIPL supports a pseudo random number generator which may be used to produce either a normal random number or a uniform random number. The C VSIPL specification has a particular random number generator defined so that it will produce the same numbers independent of the implementation. This is called a portable random number generator and is indicated during the creation of the random number state object with a flag \ttbf{VSIP\_PRNG}. The specification also supports an implementation dependent randomnumber generator using the flag \ttbf{VSIP\_NPRNG}.\\
\begin{table}[h]
\centering
\begin{tabular}{|l|l|}
\multicolumn{2}{c}{\hyperlink{randomNumbers}{Random Numbers Function Set}}\\
\hline
randcreate & Create a random number object with initial state\\
randdestroy & Destroy a random number object\\
randu & Fill a \ttbf{view} with uniform random numbers\\
randn & Fill a \ttbf{view} with normal random numbers\\
\hline
\end{tabular}
\end{table}


\chapter{Evaluation}

In this section, we first categorize \ematching patterns into three categories. Next, we evaluate our prototype of relational \ematching with two preliminary experiments, choosing patterns from each of the categories, and discussed our progress on evaluating full-system benchmarks. More experiment will be presented in the forthcoming paper.

To investigate the kinds of conjunctive queries an \ematching pattern would generate and its performance implication on the join algorithms, we categorize the \ematching patterns into three categories according to the kinds of conjunctive queries they generate:
\begin{enumerate}
    \item Linear patterns: this is the simplest form of patterns, where no variables occur more than once in the pattern. Examples of this category include $f(\alpha, \beta)$ and $f(g(\alpha),g(\beta))$).
    \item Non-linear acyclic patterns: we define non-linear acyclic patterns to be patterns that are not linear and satisfy that every multi-occurrence of a variable must occur between \enodes that has ``distance'' $\leq 1$ with each other. Examples of this category include  $f(\alpha,g(\alpha))$ and $f(f(\alpha,\beta), \alpha)$.
    \item Cyclic patterns: we define all other patterns to be cyclic patterns. Examples include $f(g(\alpha), g(\alpha))$ and $f(f(\alpha,\beta), g(\beta))$). Note that \ematching patterns of this category are always reduced to cyclic queries.
\end{enumerate}

All three categories of patterns exist in real-world applications like equality saturation.
For example, the search patterns for commutative law (e.g., $a+b$) and associative law (e.g., $(a+b)+c$) is linear, and the search patterns for the distributive law (e.g., $a\times b+a\times c$) is cyclic, while that for the rule for reciprocal (e.g., $x\times (1/x)$) is non-linear acyclic.

We choose two benchmarks from the \egg's test suites, namely the math test suite, which saturates mathematical expressions, and the lambda test suite, which saturates lambda calculus terms. Both of them are representative of a standard application of equality saturation. For example, the math test suite has many overlapping rules with Herbie \citep{herbie}, an application of equality saturation in the domain of floating-point arithmetic.

We did two preliminary experiments. The first experiment tries to understand the asymptotic speedup of relational \ematching. In this experiment, we manually write the implementation for relational \ematching for three patterns, which are representative of linear patterns, non-linear acyclic patterns, and cyclic patterns. We benchmark against the \ematching algorithm in \egg, which implements the backtracking-based \ematching algorithm described in \citet{efficient-ematching}\footnote{In fact, \egg does not implement all of the instructions of the backtracking virtual machine described in \citet{efficient-ematching}, since some of the instructions and their compilation are very complicated.}, on different \egraph sizes.

\begin{figure}
    \centering
    \includegraphics[width=\linewidth]{figures/egdb.png}
    \caption{Speedup of relational \ematching over backtracking-based \ematching algorithms}
    \label{fig:bench1}
\end{figure}

The result is shown in Figure \ref{fig:bench1}. On both cyclic and non-linear acyclic case, our relational \ematching achieves asymptotically better performance, up to 426$\times$, over backtracking-based \ematching by taking advantages of the equality constraints. In the linear
case, because no variable occurs more than once, relational \ematching
achieves similar performance as the backtracking-based \ematching up to a constant factor.\footnote{Note that the comparison here is between the handwritten relational \ematching, which is compiled, and the \ematching engine in \egg, which is interpreted, because this experiment is performed for the PLDI SRC, when we have not developed a fully working version of relational \ematching inside \egg. Therefore, the comparison is not perfectly apple-to-apple. However, we can still see the asymptotic trends.}

\begin{figure}
\vspace{-4em}
     \centering
     \begin{subfigure}[b]{0.8\textwidth}
         \centering
         \includegraphics[width=\textwidth]{figures/bench2-1.png}
         \caption{}
         \label{bench2-1}
     \end{subfigure}
     \\
     \begin{subfigure}[b]{0.8\textwidth}
         \centering
         \includegraphics[width=\textwidth]{figures/bench2-0.png}
         \caption{}
         \label{bench2-0}
     \end{subfigure}
     \caption{(a) Speedup of relationl \ematching over backtracking-based \ematching on microbenchmarks without index building time. (b) Speedup of relationl \ematching over backtracking-based \ematching on microbenchmarks with index building time.}
     \label{bench2}
\end{figure}

Next, we compare the performance of relational \ematching as we implemented in \egg against \egg's original \ematching implementation on several benchmarks. The result is presented with two figures in Figure \ref{bench2}. Figure~\ref{bench2-1} only compares the enumeration procedure of backtracking-based \ematching to that of relational \ematching, excluding time that may need to build the index before performing generic join, which are shared among different patterns, and Figure~\ref{bench2-1} makes the same comparison but includes the index building time.

According to Figure~\ref{bench2-1}, relational \ematching achieves substantial speedups for complex patterns. However, on some simple patterns, relational \ematching does not achieve a significant speedup compared to backtracking-based \ematching algorithms, and sometimes relational \ematching is slower.
Most of such patterns are linear patterns like \texttt{(+ (+ ?a ?b) ?c)} and \texttt{(fix ?v ?e)}. In particular, patterns like \texttt{(fix ?v ?e)} are equivalent to a simple enumeration of all $f$-application terms for some function symbol $f$, which we call singleton patterns. The relational \ematching has the most slowdown on several singleton patterns because running singleton patterns is very fast, taking only a few microseconds, so the overhead related to relational \ematching such as query compilation dominates the run time. Still, because they only take a few microseconds, the run time for matching such patterns are not an issue for real applications. Moreover,  note the relational \ematching performs order of magnitude  better on pattern \texttt{(* ?a ?a)}, which is a singleton pattern, as our query optimizer exploits the fact that both children of the *-application node are the same and thus only does a filter over the corresponding relation. In contrast, backtracking-based \ematching without ad hoc handling can only express this as a backtracking process, which has a larger overhead.

Comparing Figure~\ref{bench2-1} against  Figure~\ref{bench2-0}, we observe the time taken for building indices to be significant. Many plans where relational \ematching is faster now becomes slower. This is consistent with the observation made by \cite{eval-wcoj}, where index building is sometimes the bottleneck of the generic join algorithm. Since our current implementation is only a prototype, we are currently working on improving the index building time so that the performance of relational \ematching is able to dominate that of the current implemented \ematching in \egg.

Finally, our next step of experiment is to evaluate relational \ematching on full-system applications that use \egg. We attempted to run Herbie with relational \ematching as the \ematching procedure. However, we are unable to observe any significant speedup by using relational \ematching. We speculate the cause is that the workload of Herbie is running only simple, linear patterns on small \egraphs, so there are no additional equality constraints that relational \ematching could exploit. We are working on evaluating relational \ematching on other applications, such as Tensat \citep{tensat} and Szalinski \citep{2020-pldi-szalinski-cad-eqsat}.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\section{Parametric Models, Penalization, and Sample Size}

Here are a few odds and ends that may answer some of the questions you still have about Cox models.

\subsection{Parametric Survival Models}

The Cox model makes no assumptions about the baseline hazard except that it does not vary based on the values of the covariates. That makes it extremely useful for estimating the effects of different coefficients, but it also reduces its utility for prediction. By making assumptions about the shape of the baseline hazard, we get a fully parameterized model

Although we haven't gotten into confidence intervals and hypothesis


\problemname{Red, Black Cards}
%\illustration{.5}{filename}{Image by \href{url}{Author}}

John is playing a fancy card game with Bowen.
$N$ cards are laid on the table, facing down.
The cards are numbered from $1$ to $N$.
Each card has a color, and is either red or black.
The colors of the cards are unknown to John.
John's goal is to correctly identify the colors of all the cards without looking at any card.
For that, he asks Bowen $Q$ questions.
John's questions are numbered from $1$ to $Q$.
Each question may ask about whether a pair of cards have the same color, or what color a particular card has.
Bowen checks the colors of cards for John according to John's questions.
John thus receives a sequence of $Q$ answers, each being one of the following:

\begin{itemize}
\item {\tt d x y} : Card $x$ and card $y$ have different colors.
\item {\tt s x y} : Card $x$ and card $y$ have a same color.
\item {\tt r x} : Card $x$ has red color.
\item {\tt b x} : Card $x$ has black color.
\end{itemize}

However, since John asks so many questions, Bowen gets tired and sometimes made mistakes in answering the questions.
Fortunately, being a clever player, John can immediately catch Bowen's mistake if there is a contradiction from Bowen's answers.
When that happens, the current answer that results in a contradiction is void and the game proceeds.
The game ends immediately as soon as John gets enough information to identify the colors of all the cards.
The game also ends after $Q$ questions are all answered, even if John did not successfully identify the colors.

In this task, you will go over the questions asked by John and the answers to those questions given by Bowen.
You are to reproduce John's responses during the game.

\section*{Input}
The first line of the input has an integer $T$, the number of games played.\\
Each case has two integer $N, Q$ on the first line.\\
The next $Q$ lines describe John's questions and their answers.
Each line is in one of the four forms given above.\\
The first letter of each line is `{\tt d}', `{\tt s}', `{\tt r}' or `{\tt b}'.
If the letter is `{\tt d}' or `{\tt s}', the question asks about whether a pair of cards have the same color, and has two following integers giving a pair of card numbers.
If the letter is `{\tt r}' or `{\tt b}', the question asks about the color of a single card, and has one following integer giving the number of that card.\\
Duplicate questions may be asked, but it is possible that Bowen gave different answers to a same question (which results in contradiction).
\section*{Output}

There are two types of outputs, {\it response} and {\it result}.\\

If the answer to a question leads to a contradiction or John's success on the game, print a {\it response}:
\begin{itemize}
\item If it is a contradiction, output a single question mark ``{\tt ?}''.
Note that this answer is then ignored and not used for identifying colors.
\item If John can successfully identify the colors of all the cards, output ``{\tt I know}''.
The game then ends immediately and all the following questions are ignored.
\end{itemize}

Print the question number before each {\it response}.
Refer to the sample output for formatting details of question numbers.\\

At the end of the game, print the {\it result} of the game on a new line:
\begin{itemize}
\item If the game ends with John's success, output a string with $N$ letters.
The $i$-th letter is either `{\tt r}' or `{\tt b}' to describe the color of card $i$ being red or black.
\item If John is not able to identify the colors after all the $Q$ questions, output ``{\tt I am not sure}''.
\end{itemize}

\section*{Constraints}
\begin{itemize}
\item $1 \leq T\leq 15$
\item $1 \leq N \leq 10^5$
\item $1 \leq Q \leq 10^5$
\item $1\leq x, y \leq N, x \neq y$ for all the answers to John's questions.
\end{itemize}

\section*{Subtasks}
\begin{itemize}
\item Original constraints
\end{itemize}


\subsubsection{\stid{3.14} ALExa}

\paragraph{Overview}

The ALExa project ({\sl Accelerated Libraries for Exascale}) focuses on
preparing the DTK and Tasmanian libraries for exascale platforms and
integrating these libraries into ECP applications.  These libraries deliver
capabilities identified as needs of ECP applications: (1) the ability to
transfer computed solutions between grids with differing layouts on parallel
accelerated architectures, enabling multiphysics projects to seamlessly
combine results from different computational grids to perform their required
simulations (DTK); and
%
(2) the ability to construct fast and memory efficient surrogates to large
scale engineering models with multiple inputs and large number of outputs,
enabling uncertainty quantification (both forward and inverse) as well as
optimization and efficient multi-physics simulations in projects such as
ExaStar (Tasmanian).

These capabilities are being developed through ongoing interactions with our
ECP application project collaborators to ensure they will satisfy requirements
of these customers.  The libraries in turn take advantage of other ECP/SW
capabilities currently in development, including Trilinos and ForTrilinos,
Kokkos and SLATE.  The final outcome of the ECP project will be a set of
libraries deployed to facilities and also made broadly available as part of
the xSDK4ECP project.

{\bf DTK} (Data Transfer Kit)

{\it Purpose:} Transfers computed solutions between grids with differing
layouts on parallel accelerated architectures.

{\it Significance:} Coupled applications frequently have different grids with
different parallel distributions; DTK is able to transfer solution values
between these grids efficiently and accurately.

{\it Mesh and mesh-free interpolation capabilities:} multivariate data
interpolation between point clouds and grids; compactly supported radial basis
functions; nearest-neighbor and moving least square implementations; support
for standard finite-element shape functions and user-defined interpolants;
common applications include conjugate heat transfer, fluid structure
interaction, and mesh deformation.

{\it Performance portable search capabilities:} shared memory and GPU
implementations of spatial tree construction; shared memory and GPU
implementations of various spatial tree queries; MPI front-end for
coordinating distributed spatial searches between sets of geometric objects
with different decompositions; communication plan generation based on spatial
search results.

{\it URL:} https://github.com/ORNL-CEES/DataTransferKit

{\bf Tasmanian} (Toolkit for Adaptive Stochastic Modeling and Non-Intrusive
Approximation)

{\it Purpose:} Constructs efficient surrogate models for high dimensional
problems and performs parameter calibration and optimization geared towards
applications in uncertainty quantification (UQ).

{\it Significance:} UQ pertains to the statistical properties of the output
from a complex model with respect to variability in multiple model inputs;
large number of simulations are required to compute reliable statistics which
is prohibitive when dealing with computationally expensive engineering
models. A surrogate model is constructed from a moderate set of simulations
using carefully chosen input values; analysis can then be performed on the
efficient surrogate.

{\it Sparse grids capabilities:} surrogate modeling and design of experiments
(adaptive multi-dimensional interpolation); reduced (lossy) representation of
tabulated scientific data; high dimensional numerical quadrature; data mining
and manifold learning.

{\it DiffeRential Evolution Adaptive Metropolis (DREAM) capabilities:}
Bayesian inference; parameter estimation/calibration; model validation.
global optimization and optimization under uncertainty.

{\it URL:} http://tasmanian.ornl.gov

\paragraph{Key Challenges}

\indent

{\bf DTK:} General data transfer between grids of unrelated applications
requires many-to-many communication which is increasingly challenging as
communication to computation ratios are decreasing on successive HPC systems.
Search procedures to locate neighboring points and mesh cells require tree
search methods difficult to optimize on modern accelerated architectures due
to vector lane or thread divergence. Maintaining high accuracy for the
transfer requires careful attention to the mathematical properties of the
interpolation methods and is highly application-specific.

{\bf Tasmanian:} Complex models usually have significant variability in
execution time for different model inputs, which leads to massive down-time
when employing the standard fork-join adaptive sparse grid algorithms.  After
the surrogate has been constructed, collecting the samples for statistical
analysis (or multi-physics simulations) requires a massive number of basis
evaluations and many sparse and dense linear operations.

\paragraph{Solution Strategy}

\nobreak

\indent

{\bf DTK:} State-of-the-art, mathematically rigorous methods are used in DTK
to preserve accuracy of interpolated solutions.  Algorithms are implemented in
a C++ code base with extensive unit testing on multiple platforms.  Trilinos
packages are used to support interpolation methods.  Kokkos is used to achieve
performance portability across accelerated platforms.

{\bf Tasmanian:} Implement asynchronous DAG-based sparse grids construction
methods that preserve the convergence properties of the fork-join algorithms
but are insensitive to fluctuations in model simulation time.  Port the basis
evaluations and linear algebra to the GPU accelerators, and leverage the
SLATE/MAGMA capabilities to ensure performance portability across relevant
platforms.

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

\paragraph{Recent Progress}

\indent

{\bf DTK:} Extensive optimization work has yielded significant performance
improvements on accelerated and heterogeneous architectures. Work with partner
application ExaAM (WBS 2.2.1.05) created a preliminary multiphysics driver
capability for additive manufacturing simulations.

\begin{figure}[htb]
        \centering
        \includegraphics[width=3.0in]{projects/2.3.3-MathLibs/2.3.3.14-ALExa-ForTrilinos/dtk-gpu}
        \caption{\label{fig:dtk-gpu}DTK search performance relative to Boost with Intel Xeon E5-2698 and Nvidia P100. 10M points randomly distributed in a unit cube, 1M queries. The time is in seconds. Speedup in bold.}
\end{figure}

{\bf Tasmanian:} The infrastructure of Tasmanian has been upgraded to support
the broader ECP focus of the work.  GPU acceleration of sparse grid surrogates
has been implemented.  Tasmanian recently enabled the ExaStar project to
reduce the size of a large-memory table of neutrino opacities by 100X while
still preserving accuracy.

\begin{figure}[htb]
        \centering
        \includegraphics[width=1.5in]{projects/2.3.3-MathLibs/2.3.3.14-ALExa-ForTrilinos/tasmanian-gpu}
        \caption{\label{fig:tasmanian-gpu}Tasmanian approximation (right) of neutrino capacities (left).}
\end{figure}

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

\paragraph{Next Steps}

\indent

{\bf DTK:} DTK search and communication capabilities will deployed in a new,
lightweight library, ArborX, to provide these ECP investments to a broader
user base.

{\bf Tasmanian:} Work will continue with the development of the asynchronous
construction methods that exploit the native sparse grids DAG hierarchy.

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


\chapter{Advanced Topics}

\index{inheritance}
\index{generalization}

When we first looked at inheritance in Chapter~\ref{eights}, our purpose was to avoid duplicating code.
We noticed that ``decks of cards'' and ``hands of cards'' had common functionality, and we designed a \java{CardCollection} class to provide it.
This technique is an example of {\bf generalization}.
By generalizing the code, we were able to reuse it in the \java{Deck} and \java{Hand} classes.

\index{specialization}

In Chapter~\ref{conway}, we looked at inheritance from a different point of view.
When designing \java{GridCanvas} to represent a grid of cells, we extended \java{Canvas} and overrode its \java{paint} method.
This design is an example of {\bf specialization}.
Using the code provided by \java{Canvas}, we created a specialized subclass with minimal additional code.

We didn't write the code for \java{Canvas}; it's part of the Java Library.
But we were able to customize it for our own purposes.
In fact, the \java{Canvas} class was explicitly designed to be extended.

In this chapter, we'll explore the concept of inheritance more fully and explore event-driven programming.
We'll continue to develop graphical simulations as a running example, but this time in varying shapes and colors!

\section{Polygon Objects}

The word polygon means ``many angles''; the most basic polygons are triangles (3 angles), rectangles (4 angles), pentagons (5 angles), and so forth.
Polygons are an important part of computer graphics because they are used to compose more complex images.

Java provides a \java{Polygon} class (in \java{java.awt}) that we can use to represent and draw polygons.
The following code creates an empty \java{Polygon} and adds three points, forming a triangle.

\begin{code}
Polygon p = new Polygon();
p.addPoint(57, 110);
p.addPoint(100, 35);
p.addPoint(143, 110);
\end{code}

Internally, \java{Polygon} objects have three attributes:

\begin{itemize}

\item \java{public int npoints;} {\tt ~~~} \java{// total number of points}

\item \java{public int[] xpoints;} {\tt ~} \java{// array of X coordinates}

\item \java{public int[] ypoints;} {\tt ~} \java{// array of Y coordinates}

\end{itemize}

When a \java{Polygon} is created, \java{npoints} is 0 and the two arrays are initialized with length 4.
As points are added, \java{npoints} is incremented.
If \java{npoints} exceeds the length of the arrays, larger arrays are created, and the previous values are copied over (similar to how \java{ArrayList} works).

The \java{Polygon} class provides many useful methods, like \java{contains}, \java{intersects}, and \java{translate}.
We'll get to those later, but first we're going to do some specialization.

\section{Adding Color}

Specialization is useful for adding new features to an existing class, especially when you can't (or don't want to) change its design.
For example, we can extend the \java{Polygon} class by adding a \java{draw} method and a \java{Color} attribute:

\begin{code}
public class DrawablePolygon extends Polygon {
    public Color color;

    public DrawablePolygon() {
        super();
        color = Color.GRAY;
    }

    public void draw(Graphics g) {
        g.setColor(color);
        g.fillPolygon(this);
    }
}
\end{code}

As a reminder, constructors are not inherited when you extend a class.
If you don't define a constructor, the compiler will generate one that does nothing.

The constructor for \java{DrawablePolygon} uses \java{super} to invoke the constructor for \java{Polygon}, which initializes the attributes \java{npoints}, \java{xpoints}, and \java{ypoints}.
Then \java{DrawablePolygon} initializes the \java{color} attribute to \java{GRAY}.

\java{DrawablePolygon} has the same attributes and methods that \java{Polygon} has, so you can use \java{addPoint} as before, or you can directly access \java{npoints}, \java{xpoints}, and \java{ypoints} (since they are \java{public}).
You can also use methods like \java{contains}, \java{intersects}, and \java{translate}.

The following code creates a \java{DrawablePolygon} with the same points as in the previous section and sets its color to \java{GREEN}:

\begin{code}
DrawablePolygon p = new DrawablePolygon();
p.addPoint(57, 110);
p.addPoint(100, 35);
p.addPoint(143, 110);
p.color = Color.GREEN;
\end{code}

\section{Regular Polygons}

A ``regular'' polygon has all sides the same length and all angles equal in measure.
Regular polygons are a special case of polygons, so we will use specialization to define a class for them.

We could extend the \java{Polygon} class, like we did in the previous section.
But then we would not have the \java{Color} functionality we just added.
So we will make \java{RegularPolygon} extend \java{DrawablePolygon}.

To construct a \java{RegularPolygon}, we specify the number of sides, the radius (distance from the center to a vertex), and the color.
For example:

\begin{code}
RegularPolygon rp = new RegularPolygon(6, 50, Color.BLUE);
\end{code}

\begin{figure}[!ht]
\begin{center}
\includegraphics{figs/hexagon.pdf}
\caption{Determining the $x$ and $y$ coordinates of vertex V1, given the radius~$r$ and angle~$\theta$.
The center of the polygon is at the origin $(0, 0)$.}
\label{fig:hexagon}
\end{center}
\end{figure}

The constructor uses trigonometry to find the coordinates of each vertex.
Figure~\ref{fig:hexagon} illustrates the process.
The number of sides ($n=6$) and the radius ($r=50$) are given as parameters.

\begin{itemize}

\item Imagine a clock hand starting at V0 and rotating counterclockwise to V1, V2, and so forth.
In Figure~\ref{fig:hexagon}, the hand is currently at V1.

\item The angle $\theta$ is $2 \pi / n$, since there are $2\pi$ radians in a circle.
In other words, we are dividing the rotation of the clock hand into $n$ equal angles.

\item By definition, $\cos(\theta) = x/r$ and $\sin(\theta) = y/r$.
Therefore, $x = r \cos(\theta)$ and $y = r \sin(\theta)$.

\item We can determine the other $(x, y)$ coordinates by multiplying $\theta$ by $i$, where $i$ is the vertex number.

\end{itemize}

Here is the constructor for \java{RegularPolygon}:

\begin{code}
public RegularPolygon(int nsides, int radius, Color color) {

    // initialize DrawablePolygon attributes
    this.npoints = nsides;
    this.xpoints = new int[nsides];
    this.ypoints = new int[nsides];
    this.color = color;

    // the amount to rotate for each vertex (in radians)
    double theta = 2.0 * Math.PI / nsides;

    // compute x and y coordinates, centered at the origin
    for (int i = 0; i < nsides; i++) {
        double x = radius * Math.cos(i * theta);
        double y = radius * Math.sin(i * theta);
        xpoints[i] = (int) Math.round(x);
        ypoints[i] = (int) Math.round(y);
    }
}
\end{code}

This constructor initializes all four \java{DrawablePolygon} attributes, so it doesn't have to invoke \java{super()}.

It initializes \java{xpoints} and \java{ypoints} by creating arrays of integer coordinates.
Inside the \java{for} loop, it uses \java{Math.sin} and \java{Math.cos} (see Section~\ref{mathmeth}) to compute the coordinates of the vertices as floating-point numbers.
Then it rounds them off to integers, and stores them in the arrays.

When we construct a \java{RegularPolygon}, the vertices are centered at the point $(0, 0)$.
If we want the center of the polygon to be somewhere else, we can use \java{translate}, which we inherit from \java{Polygon}:

\begin{code}
RegularPolygon rp = new RegularPolygon(6, 50, Color.BLUE);
rp.translate(100, 100);
\end{code}

The result is a 6-sided polygon with radius 50 centered at the point $(100, 100)$.

% TODO suggestion from Marc Loy:
% Maybe a screenshot of a this exact polygon on a 200x200 canvas
% with some callouts on the center coordinate and radius to V0?

\section{More Constructors}

Classes in the Java library often have more than one constructor for convenience.
We can do the same with \java{RegularPolygon}.
For example, we can make the \java{color} parameter optional by defining a second constructor:

\begin{code}
public RegularPolygon(int nsides, int radius) {
    this(nsides, radius, Color.GRAY);
}
\end{code}

The keyword \java{this}, when used in a constructor, invokes another constructor in the same class.
It has a similar syntax as the keyword \java{super}, which invokes a constructor in the superclass.

Similarly, we could make the \java{radius} parameter optional too:

\begin{code}
public RegularPolygon(int nsides) {
    this(nsides, 50);
}
\end{code}

Now, suppose we invoke the \java{RegularPolygon} constructor like this:

\begin{code}
RegularPolygon rp = new RegularPolygon(6);
\end{code}

Because we provide only one integer argument, Java calls the third constructor, which calls the second one, which calls the first one.
The result is a \java{RegularPolygon} with the specified value of \java{nsides}, 6, the default value of \java{radius}, 50, and the default color, \java{GRAY}.

When writing constructors, it's a good idea to validate the values you get as arguments.
Doing so prevents run-time errors later in the program, which makes the code easier to debug.

For \java{RegularPolygon}, the number of sides should be at least three, the radius should be greater than zero, and the color should not be \java{null}.
We can add the following lines to the first constructor:

\begin{code}
public RegularPolygon(int nsides, int radius, Color color) {

    // validate the arguments
    if (nsides < 3) {
        throw new IllegalArgumentException("invalid nsides");
    }
    if (radius <= 0) {
        throw new IllegalArgumentException("invalid radius");
    }
    if (color == null) {
        throw new NullPointerException("invalid color");
    }

    // the rest of the method is omitted
\end{code}

\index{throw}
\index{Statement!throw}

In this example, we \java{throw} an exception to indicate that one of the arguments is invalid.
By default, these exceptions terminate the program and display an error message along with the stack trace.

Because we added this code to the most general constructor, we don't have to add it to the others.

\section{An Initial Drawing}
\label{sec:drawing}

Now that we have \java{DrawablePolygon} and \java{RegularPolygon}, let's take them for a test drive.
We'll need a \java{Canvas} for drawing them, so we define a new class, \java{Drawing}, that extends \java{Canvas}:

\begin{code}
public class Drawing extends Canvas {
    private ArrayList<DrawablePolygon> list;

    public Drawing(int width, int height) {
        setSize(width, height);
        setBackground(Color.WHITE);
        list = new ArrayList<DrawablePolygon>();
    }

    public void add(DrawablePolygon cp) {
        list.add(cp);
    }

    public void paint(Graphics g) {
        for (DrawablePolygon dp : list) {
            dp.draw(g);
        }
    }
}
\end{code}

The \java{Drawing} class has an \java{ArrayList} of \java{DrawablePolygon} objects.
When we create a \java{Drawing} object, the list is initially empty.
The \java{add} method takes a \java{DrawablePolygon} and adds it to the list.

\java{Drawing} overrides the \java{paint} method that it inherits from \java{Canvas}.
\java{paint} loops through the list of \java{DrawablePolygon} objects and invokes \java{draw} on each one.

Here is an example that creates three \java{RegularPolygon} objects and draws them.
Figure~\ref{fig:drawing} shows the result.

\begin{code}
public static void main(String[] args) {

    // create some regular polygons
    DrawablePolygon p1 = new RegularPolygon(3, 50, Color.GREEN);
    DrawablePolygon p2 = new RegularPolygon(6, 50, Color.ORANGE);
    DrawablePolygon p3 = new RegularPolygon(360, 50, Color.BLUE);

    // move them out of the corner
    p1.translate(100, 80);
    p2.translate(250, 120);
    p3.translate(400, 160);

    // create drawing, add polygons
    Drawing drawing = new Drawing(500, 250);
    drawing.add(p1);
    drawing.add(p2);
    drawing.add(p3);

    // set up the window frame
    JFrame frame = new JFrame("Drawing");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.add(drawing);
    frame.pack();
    frame.setVisible(true);
}
\end{code}

\label{fig:drawing}
\begin{figure}[!ht]
\begin{center}
\includegraphics[width=4in]{figs/drawing.png}
\caption{Initial drawing of three \java{RegularPolygon} objects.}
\end{center}
\end{figure}

The first block of code creates \java{RegularPolygon} objects with 3, 6, and 360 sides.
As you can see, a polygon with 360 sides is a pretty good approximation of a circle.

The second block of code translates the polygons to different locations.
The third block of code creates the \java{Drawing} and adds the polygons to it.
And the fourth block of code creates a \java{JFrame}, adds the \java{Drawing} to it, and displays the result.

Most of these pieces should be familiar, but there is one part of this program that might surprise you.
When we create the \java{RegularPolygon} objects, we assign them to \java{DrawablePolygon} variables.
%, and then pass them to \java{Drawing.add}, which requires \java{DrawablePolygon} objects.
It might not be obvious why that's legal.

\index{IS-A}

\java{RegularPolygon} extends \java{DrawablePolygon}, so every \java{RegularPolygon} object is also a \java{DrawablePolygon}.
The parameter of \java{Drawing.add} has to be a \java{DrawablePolygon}, but it can be any type of \java{DrawablePolygon}, including \java{RegularPolygon} and other subclasses.

\index{polymorphism}

This design is an example of {\bf polymorphism}, a fancy word that means ``having many forms''.
\java{Drawing.add} is polymorphic method, because the parameter can be one of many types.
And the \java{ArrayList} in \java{Drawing} is a polymorphic data structure, because the elements can be different types.

%At compile-time, \java{p1} is treated like a \java{DrawablePolygon}.
%But at run-time, \java{p1} is actually a \java{RegularPolygon}.

%What's interesting about this example is that the polygon objects have methods from multiple classes.
%The constructor is defined in \java{RegularPolygon}.
%The \java{translate} method is defined in \java{Polygon}.
%The \java{draw} method (called by \java{paint}) is defined in \java{DrawablePolygon}.
%And yet, everything works together seamlessly.

\section{Blinking Polygons}

At this point, we have a simple program that draws polygons; we can make it more fun by adding animation.
Chapter~\ref{conway} introduced the idea of simulating time steps.
Here's a loop that runs the animation.

\begin{code}
while (true) {
    drawing.step();
    try {
        Thread.sleep(1000 / 30);
    } catch (InterruptedException e) {
        // do nothing
    }
}
\end{code}

Each time through the loop, we call \java{step} to update the \java{Drawing}.
Then we sleep with a delay calculated to update about 30 times per second.

Here's what the \java{step} method of \java{Drawing} looks like:

\begin{code}
public void step() {
    for (DrawablePolygon dp : list) {
        dp.step();
    }
    repaint();
}
\end{code}

It invokes \java{step} on each \java{DrawablePolygon} in the list and then repaints (clears and redraws) the canvas.

In order for this code to compile, we need \java{DrawablePolygon} to provide a \java{step} method.
Here's a version that doesn't do anything; we'll override it in subclasses.

\begin{code}
public void step() {
    // do nothing
}
\end{code}

Now let's design a new type of polygon that blinks.
We'll define a class named \java{BlinkingPolygon} that extends \java{RegularPolygon} and adds two more attributes: \java{visible}, which indicates whether the polygon is visible, and \java{count}, which counts the number of time steps since the last blink.

\begin{code}
public class BlinkingPolygon extends RegularPolygon {
    public boolean visible;
    public int count;

    public BlinkingPolygon(int nsides, int radius, Color c) {
        super(nsides, radius, c);
        visible = true;
        count = 0;
    }

    public void draw(Graphics g) {
        if (visible) {
            super.draw(g);
        }
    }

    public void step() {
        count++;
        if (count == 10) {
            visible = !visible;
            count = 0;
        }
    }
}
\end{code}

The constructor uses \java{super} to call the \java{RegularPolygon} constructor.
Then it initializes \java{visible} and \java{count}.
Initially the \java{BlinkingPolygon} is visible.

The \java{draw} method draws the polygon only if it is visible.
It uses \java{super} to call \java{draw} in the parent class.
But the parent class is \java{RegularPolygon}, which does not provide a \java{draw} method.
In this case, \java{super} invokes \java{draw} from the \java{DrawablePolygon} class.

The \java{step} method increments \java{count}.
Every 10 time steps, it toggles \java{visible} and resets \java{count} to 0.

\section{Interfaces}

You might be getting tired of polygons at this point.
Can't we draw anything else?
Of course we can, but \java{Drawing} is currently based on \java{DrawablePolygon}.
To draw other types of objects, we have to generalize the code.

The \java{Drawing} class does essentially three things: (1) it maintains a \java{list} of objects, (2) it invokes the \java{draw} method on each object, and (3) it invokes the \java{step} method on each object.

So here's one way we could make the code more general:

\begin{enumerate}

\item Define a new superclass, which we call \java{Actor}, that provides the two methods needed by \java{Drawing}:

\begin{code}
public class Actor {
    public void draw(Graphics g) {
        // do nothing
    }
    public void step() {
        // do nothing
    }
}
\end{code}

\item In the \java{Drawing} class, replace \java{DrawablePolygon} with \java{Actor}.

\item Any class that we want to draw must now extend \java{Actor}.

\end{enumerate}

There's just one problem: \java{DrawablePolygon} already extends \java{Polygon}, and classes can only extend one superclass.
Also, the \java{Actor} class seems pointless, since the methods it defines don't do anything.

\index{inheritance}

Java provides another mechanism for inheritance that solves these problems.
We can define \java{Actor} as an \java{interface} instead of a \java{class}, like this:

\begin{code}
public interface Actor {
    void draw(Graphics g);
    void step();
}
\end{code}

\index{interface}

Like a class definition, an {\bf interface} definition contains methods.
But it contains only the declarations of the methods, not their implementations.

Like an abstract class, an interface specifies methods that must be provided by subclasses.
The difference is that an abstract class can implement some methods; an interface cannot.

All interface methods are \java{public} by default, since they are intended to be used by other classes.
So there is no need to declare them as \java{public}.

To inherit from an interface, you use the keyword \java{implements} instead of \java{extends}.
Here's a version of \java{DrawablePolygon} that extends \java{Polygon} and implements \java{Actor}.
So it inherits methods from \java{Polygon}, and it is required to provide the methods in \java{Actor}, namely \java{step} and \java{draw}.

\begin{code}
public class DrawablePolygon extends Polygon implements Actor {
    // rest of the class omitted
}
\end{code}

In terms of inheritance, \java{DrawablePolygon} is both a \java{Polygon} and an \java{Actor}.
So the following assignments are legal:

\begin{code}
Polygon p1 = new DrawablePolygon();
Actor a2 = new DrawablePolygon();
\end{code}

And the same is true for subclasses of \java{DrawablePolygon}; these assignments are legal, too:

\begin{code}
Polygon p2 = new RegularPolygon(5, 50, Color.YELLOW);
Actor a2 = new RegularPolygon(5, 50, Color.YELLOW);
\end{code}

\index{polymorphism}

Interfaces are another example of polymorphism.
\java{a1} and \java{a2} are the same type of variable, but they refer to objects with different types.
And similarly with \java{p1} and \java{p2}.

% But each of them provides the \java{draw} and \java{step} methods specified in the \java{Actor} interface.

Classes may extend only one superclass, but they may implement as many interfaces as needed.
Java Library classes often implement multiple interfaces.

\section{Event Listeners}

\index{sprite}

Now that our \java{Drawing} is based on \java{Actor} instead of \java{DrawablePolygon}, we can draw other types of graphics.
Here is the beginning of a class that reads an image from a file and shows the image moving across the canvas.
The class is called \java{Sprite} because a moving image is sometimes called a {\bf sprite}, in the context of computer graphics.

\begin{code}
public class Sprite implements Actor, KeyListener {
    private int xpos;
    private int ypos;
    private int dx;
    private int dy;
    private Image image;

    public Sprite(String path, int xpos, int ypos) {
        this.xpos = xpos;
        this.ypos = ypos;
        try {
            this.image = ImageIO.read(new File(path));
        } catch (IOException exc) {
            exc.printStackTrace();
        }
    }
}
\end{code}

The instance variables \java{xpos} and \java{ypos} represent the location of the sprite.
\java{dx} and \java{dy} represent the velocity of the sprite in the $x$ and $y$ directions.

The constructor takes as parameters the name of a file and the initial position.
It uses  \java{ImageIO}, from the \java{javax.imageio} package, to read the file.
If an error occurs during reading, an \java{IOException} is caught, and the program displays the stack trace for debugging.

\java{Sprite} implements two interfaces: \java{Actor} and \java{KeyListener}.
\java{Actor} requires that we provide \java{draw} and \java{step} methods:

\begin{code}
    public void draw(Graphics g) {
        g.drawImage(image, xpos, ypos, null);
    }

    public void step() {
        xpos += dx;
        ypos += dy;
    }
\end{code}

The \java{draw} method draws the image at the sprite's current position.
The \java{step} method changes the position based on \java{dx} and \java{dy}, which are initially zero.

\java{KeyListener} is an interface for receiving keyboard events, which means we can detect and respond to key presses.
A class that implements \java{KeyListener} has to provide the following methods:

\begin{itemize}

\item \java{void keyPressed(KeyEvent e);}
\\ Invoked when a key has been ``pressed''.
This method is invoked repeatedly while a key is being held down.

\item \java{void keyReleased(KeyEvent e);}
\\ Invoked when a key has been ``released'', meaning it is no longer down.

\item \java{void keyTyped(KeyEvent e);}
\\ Invoked when a key has been ``typed'', which generally means it has been both pressed and released.

\end{itemize}

These methods get invoked when the user presses and releases {\em any} key.
They take a \java{KeyEvent} object as a parameter, which specifies which key was pressed, released, or typed.

We can use these methods to design a simple animation using the arrow keys.
When the user presses up or down, the sprite will move up or down.
When the user presses left or right, the sprite will move left or right.

Here's an implementation of \java{keyPressed} that uses a \java{switch} statement to test which arrow key was pressed and sets \java{dx} or \java{dy} accordingly.
(There is no \java{default} branch, so we ignore all other keys.)

\begin{code}
public void keyPressed(KeyEvent e) {
    switch (e.getKeyCode()) {
        case KeyEvent.VK_UP:
            dy = -5;
            break;
        case KeyEvent.VK_DOWN:
            dy = +5;
            break;
        case KeyEvent.VK_LEFT:
            dx = -5;
            break;
        case KeyEvent.VK_RIGHT:
            dx = +5;
            break;
    }
}
\end{code}

The values of \java{dx} and \java{dy} determine how much the sprite moves each time \java{step} is invoked.
While the user holds down an arrow key, the sprite will move at a constant speed.

Here's an implementation of \java{keyReleased} that runs when the user releases the key.

\begin{code}
public void keyReleased(KeyEvent e) {
    switch (e.getKeyCode()) {
        case KeyEvent.VK_UP:
        case KeyEvent.VK_DOWN:
            dy = 0;
            break;
        case KeyEvent.VK_LEFT:
        case KeyEvent.VK_RIGHT:
            dx = 0;
            break;
    }
}
\end{code}

When the user releases the key, \java{keyReleased} sets \java{dx} or \java{dy} to 0, so the sprite stops moving in that direction.

We don't need the \java{keyTyped} method for this example, but it's required by the interface; if we don't provide one, the compiler will complain.
So we provide an implementation that does nothing:

\begin{code}
public void keyTyped(KeyEvent e) {
    // do nothing
}
\end{code}

Now, here's the code we need to create a \java{Sprite}, add it to a \java{Drawing}, and configure it as a \java{KeyListener}:

\begin{code}
Sprite sprite = new Sprite("face-smile.png", 25, 150);
drawing.add(sprite);
drawing.addKeyListener(sprite);
drawing.setFocusable(true);
\end{code}

Recall that the \java{add} method is one that we wrote in Section~\ref{sec:drawing}.
It adds an \java{Actor} to the list of objects to be drawn.

The \java{addKeyListener} method is inherited from \java{Canvas}.
It adds a \java{KeyListener} to the list of objects that will receive key events.

In graphical applications, key events are only sent to components when they have the keyboard focus.
The \java{setFocusable} method ensures that \java{drawing} will be have the focus initially, without the user having to click on it first.

\section{Timers}

%When you run this program, the arrow keys might not work initially.
%If that happens, click on the drawing to give it the keyboard focus.

Now that you know about interfaces and events, we can show you a better way to create animations.
Previously, we implemented the animation loop using \java{while (true)} and \java{Thread.sleep}.
Java provides a \java{Timer} class (in \java{javax.swing}) that encapsulates this behavior.

A \java{Timer} is useful for executing code at regular intervals.
The constructor for \java{Timer} takes two parameters:

\begin{itemize}
\item \java{int delay} {\tt ~~~~~~~~~~~~~~~} \java{// milliseconds between events}

\item \java{ActionListener listener} {\tt ~} \java{// for handling timer events}
\end{itemize}

The \java{ActionListener} interface requires only one method, \java{actionPerformed}.
This is the method the \java{Timer} invokes after the given delay.

Using a \java{Timer}, we can reorganize the code in \java{main} by defining a class that implements \java{ActionListener}.

\begin{code}
public class VideoGame implements ActionListener {
    private Drawing drawing;

    public VideoGame() {
        Sprite sprite = new Sprite("face-smile.png", 50, 50);
        drawing = new Drawing(800, 600);
        drawing.add(sprite);
        drawing.addKeyListener(sprite);
        drawing.setFocusable(true);

        JFrame frame = new JFrame("Video Game");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(drawing);
        frame.pack();
        frame.setVisible(true);
    }

    public void actionPerformed(ActionEvent e) {
        drawing.step();
    }

    public static void main(String[] args) {
        VideoGame game = new VideoGame();
        Timer timer = new Timer(33, game);
        timer.start();
    }
}
\end{code}

The \java{main} method constructs a \java{VideoGame} object, which creates a \java{Sprite}, a \java{Drawing}, and a \java{JFrame}.
Then it constructs a \java{Timer} object and starts the timer.
Every 33 milliseconds, the \java{Timer} invokes \java{actionPerformed}, which invokes \java{step} on the \java{Drawing}.

\java{Drawing.step} invokes \java{step} on all of its \java{Actor} objects, which causes them to update their position, color, or other aspects of their appearance.
The \java{Drawing.step} then repaints the \java{Canvas}, and the time step is done.

At this point you have all of the elements you need to write your own video games.
In the exercises at the end of this chapter, we have some suggestions for getting started.

We hope this final chapter has been a helpful summary of topics presented throughout the book, including input and output, decisions and loops, classes and methods, arrays and objects, inheritance, and graphics.
Congratulations on making it to the end!

\section{Vocabulary}

\begin{description}

\term{generalization}
The process of extracting common code from two or more classes and moving it into a superclass.

\term{specialization}
Extending a class to add new attributes or methods, or to modify existing behavior.

\term{polymorphism}
A language feature that allows objects to be assigned to variables of related types.

\term{sprite}
A computer graphic which may be moved or otherwise manipulated on the screen.

\end{description}

\section{Exercises}

% TODO: We need to divide up the code for this chapter, removing the solution code and making the code in ThinkJavaCode2 more consistent with the chapter.

The code for this chapter is in the {\tt ch16} directory of {\tt ThinkJavaCode2}.
See page~\pageref{code} for instructions on how to download the repository.
Before you start the exercises, we recommend that you compile and run the examples.

The following exercises give you a chance to practice using the features in this chapter by extending the example code.

\begin{exercise}
The \java{Polygon} class does not provide a \java{toString} method; it inherits the default \java{toString} from \java{java.lang.Object}, which only includes the class's name and memory location.
Write a more useful \java{toString} method for \java{DrawablePolygon} that includes its $(x, y)$ points.
\end{exercise}

\begin{exercise}
Write a class \java{MovingPolygon} that extends \java{RegularPolygon} and implements \java{Actor}.
It should have instance variables \java{posx} and \java{posy} that specify its position and \java{dx} and \java{dy} that specify its velocity (and direction).
During each time step, it should update its position.
If it gets to the edge of the \java{Drawing}, it should reverse direction by changing the sign of \java{dx} or \java{dy}.
\end{exercise}

\begin{exercise}
Modify the \java{VideoGame} class so it displays a \java{Sprite} and a \java{MovingPolygon} (from the previous exercise).
Add code that detects collisions between \java{Actor} objects in the same \java{Drawing}, and invoke a method on both objects when they collide.
Hint: You might want to add a method to the \java{Actor} interface, guaranteeing that all \java{Actor} objects know how to handle collisions.
\end{exercise}

\begin{exercise}
Java provides other event listeners that you can implement to make your programs interactive.
For example, the interfaces \java{MouseListener}, \java{MouseMotionListener}, and \java{MouseWheelListener} allow you to respond to mouse input.
Use the \java{MouseListener} interface to implement an \java{Actor} that can respond to mouse clicks.
\end{exercise}


\documentclass[twocolumn]{scrartcl}

\usepackage[utf8]{inputenc}

\usepackage{fixltx2e}

% Step environment
% <https://tex.stackexchange.com/a/12943/13262>
\usepackage{amsthm}
\newtheorem*{remark}{Remark}
%
\newtheoremstyle{named}{}{}{\itshape}{}{\bfseries}{.}{.5em}{\thmnote{#1 }#3}
\theoremstyle{named}
\newtheorem*{step}{Step}

\usepackage{microtype}
\usepackage{amsmath}
\usepackage{mathtools}
\usepackage{booktabs}
\usepackage{tabularx}

\usepackage{pgfplots}
\pgfplotsset{compat=newest}

\usepackage{siunitx}

\newcommand\mytitle{Algorithmic improvements for the CIECAM02 and CAM16 color appearance models}
\newcommand\myauthor{Nico Schlömer}

\usepackage[
  pdfencoding=unicode,
  ]{hyperref}
\hypersetup{
  pdfauthor={\myauthor},
  pdftitle={\mytitle}
}

% <https://tex.stackexchange.com/a/43009/13262>
\DeclarePairedDelimiter\abs{\lvert}{\rvert}%

\usepackage[T1]{fontenc}
\usepackage{newtxtext}
\usepackage{newtxmath}

% degree symbol
\usepackage{gensymb}

% % <https://tex.stackexchange.com/a/413899/13262>
% \usepackage{etoolbox}
% \makeatletter
% \long\def\etb@listitem#1#2{%
%   \expandafter\ifblank\expandafter{\@gobble#2}
%     {}
%     {\expandafter\etb@listitem@i
%      \expandafter{\@secondoftwo#2}{#1}}}
% \long\def\etb@listitem@i#1#2{#2{#1}}
% \makeatother

% Okay. Don't use biblatex/biber for now. There are breaking changes in every
% revision, and we'd have to stick to the exact version that arxiv.org has,
% otherwise it's error messages like
% ```
% Package biblatex Warning: File 'main.bbl' is wrong format version
% - expected 2.8.
% ```
% \usepackage[sorting=none]{biblatex}
% \bibliography{bib}

\usepackage{amsmath}
\DeclareMathOperator{\sign}{sign}

\usepackage{bm}
\newcommand\rgb{\bm{R}}

\title{\mytitle\footnote{The LaTeX sources of this article are on \url{https://github.com/nschloe/note-on-cam16}}}
\author{\myauthor}

\begin{document}

\maketitle
\begin{abstract}
  This note is concerned with the CIECAM02 color appearance model and its
  successor, the CAM16 color appearance model. Several algorithmic flaws are
  pointed out and remedies are suggested. The resulting color model is
  algebraically equivalent to CIECAM02/CAM16, but shorter, more efficient, and
  works correctly for all edge cases.
\end{abstract}

\section{Introduction}

The CIECAM02 color appearance model~\cite{ciecam02} has attracted much
attention and was generally thought of as a successor to the ever so popular
CIELAB color model. However, it was quickly discovered that CIECAM02 breaks
down for certain input values. A fair number of research articles suggests
fixes for this behavior, most of them by modifying the first steps of the
forward model. Luo and Li give an overview of the suggested
improvements~\cite{ciecam02-recent}; see references therein.  Most recently,
Li and Luo~\cite{cam16} gave their own suggestion on how to best
circumvent the breakdown~\cite{cam16}. The updated algorithm differs from the
original CIECAM02 only in the first steps of the forward model.

It appears that that the rest of the algorithm has not received much attention
over the years. In both CIECAM02 and its updated version CAM16, some of the
steps are more complicated than necessary, and in edge cases lead to break
downs once again. The present document describes those flaws and suggests
improvements (Section~\ref{sec:ff}). The resulting model description
(Section~\ref{sec:full}) is entirely equivalent to the CIECAM02/CAM16, but is
simpler -- hence faster and easier to implement -- and works in all edge
cases.

All findings in this article are implemented in the open-source software package
colorio~\cite{colorio}.

\section{Flaws and fixes}\label{sec:ff}

This section describes the flaws of CAM16 and suggests fixes for them. Some of
them are trivial, others are harder to see. All listed steps also appear in the
CIECAM02 color appearance model and trivially apply there.

\subsection{Step 3, forward model}

The original Step 3 of the forward model reads

\begin{step}[3]
Calculate the postadaptation cone response
(resulting in dynamic range compression).
\[
  R_a = 400 \frac{\left(\frac{F_L R_c}{100}\right)^{0.42}}{\left(\frac{F_L R_c}{100}\right)^{0.42} + 27.13} + 0.1
\]
If $R_c$ is negative, then
\[
  R_a = -400 \frac{\left(\frac{-F_L R_c}{100}\right)^{0.42}}{\left(\frac{-F_L R_c}{100}\right)^{0.42} + 27.13} + 0.1
\]
and similarly for the computations of $G_a$ and $B_a$.
\end{step}

If the $\sign$ operator is used here as it is used later in step 5 of the
inverse model, the above description can be shortened.

Furthermore, the term $0.1$ is added here, but in all of the following steps in
which $R_a$ is used -- except the computation of $t$ in Step 9 --, it cancels
out algebraically.  Unfortunately, said cancellation is not always exact when
computed in floating point arithmetic. Luckily, the adverse effect of such
rounding errors is rather limited here. The results will only be distorted for
very small input values, e.g., $X=Y=Z=0$; see Table~\ref{tab:zero}. For the
sake of consistency, it is advisable to include the term $0.1$ only in the
computation of $t$ in Step 9:
\[
  R'_a = 400 \sign(R_c) \frac{{\left(\frac{F_L \abs{R_c}}{100}\right)}^{0.42}}{{\left(\frac{F_L \abs{R_c}}{100}\right)}^{0.42} + 27.13}.
\]

\begin{table}\centering
  \begin{tabularx}{\linewidth}{XXX}
  \toprule
          & with fixes & without\\
  \midrule
    $J$ & \texttt{0.0} & \texttt{3.258e-22}\\
    $C$ & \texttt{0.0} & \texttt{4.071e-24}\\
    $h$ & \texttt{0.0} & \texttt{0.0}\\
    $Q$ & \texttt{0.0} & \texttt{2.233e-10}\\
    $M$ & \texttt{0.0} & \texttt{2.943e-24}\\
    $s$ & \texttt{0.0} & \texttt{1.148e-05}\\
  \bottomrule
\end{tabularx}
\caption{CAM16 values upon input $X=Y=Z=0$ with and without the fixes in
  this article.  The exact solutions are zeros for every
  entry.}\label{tab:zero}
\end{table}

\subsection{Linear combinations, forward model}

In the forward model, four linear combinations of $R'_a$, $G'_a$, and $B'_a$
have to be formed. They can conveniently be expressed as the matrix-vector
multiplication
\[
  \begin{pmatrix}
    p'_2\\[0.5ex]
    a\\[0.5ex]
    b\\[0.5ex]
    u
  \end{pmatrix}
  \coloneqq
  \begin{pmatrix}
    2 & 1 & \tfrac{1}{20}\\[0.5ex]
    1 & -\tfrac{12}{11} & \tfrac{1}{11}\\[0.5ex]
    \tfrac{1}{9} & \tfrac{1}{9} & -\tfrac{2}{9}\\[0.5ex]
    1 & 1 & \tfrac{21}{20}
  \end{pmatrix}
  \begin{pmatrix}
    R'_a\\G'_a\\B'_a
  \end{pmatrix}
\]
which on many platforms can be computed significantly faster than four
individual dot-products.
The last variable $u$ is used in the computation of $t$ in step 9.

\subsection{Step 9, forward model}

\begin{step}[9]
  Calculate the correlates of [\dots] saturation ($s$).
  \[
    s \coloneqq 100 \sqrt{M/Q}.
  \]
\end{step}
This expression is not well-defined if $Q=0$, a value occurring if the
input values are $X=Y=Z=0$. When making use of the definition of $M$ and $Q$,
one gets to an expression for $s$ that is well-defined in all cases:
\begin{align}
  \label{eq:alpha}
  \alpha&\coloneqq t^{0.9} {(1.64-0.29^n)}^{0.73},\\
  \nonumber
  s &\coloneqq 50 \sqrt{\frac{c\alpha}{A_w + 4}}.
\end{align}

\subsection{Steps 2 and 3, inverse model}

\begin{step}[2]
Calculate $t$, $e_t$, $p_1$, $p_2$, and $p_3$.
\begin{align*}
  t &= {\left(\frac{C}{\sqrt{\frac{J}{100}} {(1.64 - 0.29^n)}^{0.73}}\right)}^\frac{1}{0.9},\\
  e_t &= \frac{1}{4} \left[\cos(h'\pi/180\degree + 2) + 3.8\right],\\
  p_1 &= \frac{50000}{13} N_c N_{cb} e_t \frac{1}{t},\\
  p_2 &= \frac{A}{N_{bb}} + 0.305,\\
  p_3 &= \frac{21}{20}.
\end{align*}
\end{step}

\begin{step}[3]
Calculate $a$ and $b$.
If $t=0$, then $a=b=0$ and go to Step 4.
In the next computations be sure transform $h$ from degrees to radians before
calculating $\sin(h)$ and $\cos(h)$: If $\abs{\sin(h)} \ge \abs{\cos(h)}$
then
\begin{align*}
  p_4 &= \frac{p_1}{\sin(h)},\\
  b &= \frac{p_2 (2+p_3) \frac{460}{1403}}{p_4 + (2+p_3) \frac{220}{1403} \frac{\cos(h)}{\sin(h)} - \frac{27}{1403} + p_3 \frac{6300}{1403}},\\
  a &= b \frac{\cos(h)}{\sin(h)}.
\end{align*}
If $\abs{\cos(h)} > \abs{\sin(h)}$ then
\begin{align*}
  p_5 &= \frac{p_1}{\cos(h)},\\
  a &= \frac{p_2 (2+p_3) \frac{460}{1403}}{%
    p_5
    + (2+p_3) \frac{220}{1403} -
    \left(\frac{27}{1403}  - p_3 \frac{6300}{1403}\right) \frac{\sin(h)}{\cos(h)}
  },\\
  b &= a \frac{\sin(h)}{\cos(h)}.
\end{align*}
\end{step}

Some of the complications in this step stem from the fact that the variable $t$
might be $0$ in the denominator of $p_1$. Likewise, the distinction of cases in $\sin(h)$ and $\cos(h)$ is necessary
to avoid division by $0$ in $a$ and $b$.

It turns out that both of these problems can be avoided quite elegantly.
Consider, in the case $\abs{\sin(h)} \ge \abs{\cos(h)}$:
\begin{align*}
  p'_1 &\coloneqq \frac{50000}{13} N_c N_{cb} e_t,\\
  b &= \frac{p_2 (2+p_3) \frac{460}{1403}}{\frac{p'_1}{t\sin(h)} + (2+p_3) \frac{220}{1403} \frac{\cos(h)}{\sin(h)} - \frac{27}{1403} + p_3 \frac{6300}{1403}}\\
   &= \frac{t \sin(h) p_2 (2+p_3) \frac{460}{1403}}{p'_1 + t (2+p_3) \frac{220}{1403} \cos(h) + t \sin(h) \frac{6588}{1403}}\\
   &= \frac{23 t \sin(h) p_2}{23 p'_1 + 11 t \cos(h) + 108 t \sin(h)},
\end{align*}
and
\[
  a = \frac{23 t \cos(h) p_2}{23 p'_1 + 11 t \cos(h) + 108 t \sin(h)}.
\]
Conveniently, the exact same expressions are retrieved in the case
$\abs{\cos(h)} > \abs{\sin(h)}$. These expressions are always well-defined since
\begin{multline*}
  23 p'_1 + 11 t \cos(h) + 108 t \sin(h)\\
  = \frac{23 p'_1 p_2}{R'_a + G'_a + \tfrac{21}{20}B'_a + 0.305}
  > 0.
\end{multline*}

In the algorithm, the value of $t$ can be retrieved via
$\alpha$~\eqref{eq:alpha} from the input variables. Indeed, if the saturation
correlate $s$ is given, one has
\[
  \alpha \coloneqq {\left(\frac{s}{50}\right)}^2 \frac{A_w+4}{c};
\]
if $M$ is given, one can compute $C\coloneqq M / F_L^{0.25}$ and then
\[
\alpha\coloneqq\begin{dcases*}
  0 &if $J=0$,\\
  \frac{C}{\sqrt{J/100}}&otherwise.
\end{dcases*}
\]
It is mildly unfortunate that one has to introduce a case distinction for
$J=0$ here, but this is an operation that can still be performed at reasonable
efficiency.

\begin{figure}
\input{perf.tex}
  \caption{Performance comparison of the conversion from CAM16 to XYZ (with
  $J$, $C$, and $h$), implemented in colorio~\cite{colorio}. The suggested
  improvements in the inverse model lead to a speed-up of about 5\%.}
\end{figure}

\appendix
\section{Full model\label{sec:full}}

For the convenience of the reader, both forward and inverse steps of the
improved CAM16 algorithm are given here. The wording is taken from~\cite{cam16}
where applicable.
The steps that differ from the original model are marked with an asterisk~(*).

As an abbreviation, the bold letter $\rgb$ is used whenever the equation applies
to $R$, $G$, and $B$ alike.

\paragraph{Illuminants, viewing surrounds set up and background
parameters}
(See the note at the end of Part 2 of Appendix B of~\cite{cam16} for determining
all parameters.)

\begin{itemize}
  \item Adopted white in test illuminant: $X_w$, $Y_w$, $Z_w$
  \item Background in test conditions: $Y_b$
  \item Reference white in reference illuminant:
    $X_{wr}=Y_{wr} = Z_{wr}=100$, fixed in the model
  \item Luminance of test adapting field (\si{\candela\per\meter\squared}): $L_A$.
$L_A$ is computed using
    \[
      L_A = \frac{E_W}{\pi} \frac{Y_b}{Y_W} = \frac{L_W Y_b}{Y_W},
    \]
  where $E_W =\pi L_W$ is the illuminance of reference white in \si{\lux};
    $L_W$ is the luminance of reference white in
    \si{\candela\per\meter\squared}; $Y_b$ is the luminance factor of the
    background; and $Y_w$ is the luminance factor of the reference white.

  \item Surround parameters are given in Table~\ref{tab:surround}:
To determine the surround conditions see the note at the
    end of Part 1 of Appendix A of~\cite{cam16}.
\item $N_c$ and $F$ are modelled as a function of $c$, and their values
  can be linearly interpolated, using the data from~\ref{tab:surround}.
\end{itemize}

Let $M_{16}$ be given by
\[
  M_{16} \coloneqq \begin{pmatrix}
    0.401288  & 0.650173 & -0.051461\\
    -0.250268 & 1.204414 & 0.045854\\
    -0.002079 & 0.048952 & 0.953127
  \end{pmatrix}.
\]

\subsection{Forward model}

\begin{step}[0*]
Calculate all values/parameters which are independent
of the input sample.
\begin{align*}
  &\begin{pmatrix}R_w\\G_w\\B_w\end{pmatrix}
    = M_{16}
  \begin{pmatrix}X_w\\Y_w\\Z_w\end{pmatrix},\\
  &D = F \left[1 - \tfrac{1}{3.6} \exp\left(\tfrac{-L_a-42}{92}\right)\right].
\end{align*}
If $D$ is greater than one or less than zero, set it to one or zero,
respectively.
\begin{align*}
  &D_{\rgb} = D\frac{Y_W}{\rgb_W} -1 + D,\\
  &k = \frac{1}{5L_A + 1},\\
  &F_L = k^4 L_A + 0.1 {(1-k^4)}^2 {(5L_A)}^{1/3},\\
  &n = \frac{Y_b}{Y_W},\\
  &z = 1.58 + \sqrt{n},\\
  &N_{bb} = \frac{0.725}{n^{0.2}},\\
  &N_{cb} = N_{bb},\\
  &\rgb_{wc} = D_{\rgb} \rgb_w,\\
  &\rgb_{aw} = 400
  \frac
  {{\left(\frac{F_L \rgb_{wc}}{100}\right)}^{0.42}}
  {{\left(\frac{F_L \rgb_{wc}}{100}\right)}^{0.42} + 27.13},\\
  &A_w = \left(2R_{aw} + G_{aw} + \tfrac{1}{20} B_{aw}\right) \cdot N_{bb}.
\end{align*}
\end{step}

\begin{table}\centering
  \begin{tabularx}{\linewidth}{XXXX}
  \toprule
          & $F$ & $c$   & $N_c$\\
  \midrule
  Average & 1.0 & 0.69  & 1.0\\
  Dim     & 0.9 & 0.59  & 0.9\\
  Dark    & 0.8 & 0.525 & 0.8\\
  \bottomrule
\end{tabularx}
  \caption{Surround parameters.}\label{tab:surround}
\end{table}

\begin{table}\centering
  \begin{tabularx}{\linewidth}{XXXXXX}
  \toprule
        & Red   & Yellow & Green & Blue   & Red\\
  \midrule
  $i$   & 1     & 2     & 3      & 4      & 5\\
  $h_i$ & 20.14 & 90.00 & 164.25 & 237.53 & 380.14\\
  $e_i$ & 0.8   & 0.7   & 1.0    & 1.2    & 0.8\\
  $H_i$ & 0.0   & 100.0 & 200.0  & 300.0  & 400.0\\
  \bottomrule
\end{tabularx}
  \caption{Unique hue data for calculation of hue quadrature.}\label{table:hue}
\end{table}

\begin{step}[1]
Calculate `cone' responses.
\[
\begin{pmatrix}R\\G\\B\end{pmatrix}
= M_{16} \begin{pmatrix}X\\Y\\Z\end{pmatrix}
\]
\end{step}

\begin{step}[2]
Complete the color adaptation of the illuminant in
the corresponding cone response space (considering various
luminance levels and surround conditions included in $D$, and
hence in $D_R$, $D_G$, and $D_B$).
\[
  \rgb_c = D_{\rgb} \cdot \rgb
\]
\end{step}

\begin{step}[3*]
Calculate the modified postadaptation cone response
(resulting in dynamic range compression).
\[
  \rgb'_a = 400 \sign(\rgb_c)
    \frac
    {{\left(\frac{F_L \abs{\rgb_c}}{100}\right)}^{0.42}}
    {{\left(\frac{F_L \abs{\rgb_c}}{100}\right)}^{0.42} + 27.13}.
\]
\end{step}

\begin{step}[4*]
Calculate Redness--Greenness ($a$), Yellowness--Blueness ($b$) components,
  hue angle ($h$), and auxiliary variables ($p'_2$, $u$).
\begin{align*}
  \begin{pmatrix}
    p'_2\\[0.5ex]
    a\\[0.5ex]
    b\\[0.5ex]
    u
  \end{pmatrix}
  &\coloneqq
  \begin{pmatrix}
    2 & 1 & \tfrac{1}{20}\\[0.5ex]
    1 & -\tfrac{12}{11} & \tfrac{1}{11}\\[0.5ex]
    \tfrac{1}{9} & \tfrac{1}{9} & -\tfrac{2}{9}\\[0.5ex]
    1 & 1 & \tfrac{21}{20}
  \end{pmatrix}
  \begin{pmatrix}
    R'_a\\G'_a\\B'_a
  \end{pmatrix},\\
  % a&\coloneqq R'_a - \tfrac{12}{11} G'_a + \tfrac{1}{11} B'_a\\
  % b&\coloneqq \tfrac{1}{9} R'_a + \tfrac{1}{9} G'_a - \tfrac{2}{9} B'_a\\
  h&\coloneqq \arctan(b/a).
\end{align*}
(Make sure that $h$ is between $0\degree$ and $360\degree$.)
\end{step}

\begin{step}[5]
Calculate eccentricity [$e_t$, hue quadrature composition
($H$) and hue composition ($H_c$)].

Using the following unique hue data in table~\ref{table:hue}, set
$h'= h + 360\degree$ if $h < h_1$, otherwise $h'=h$.
Choose a proper $i\in\{1,2,3,4\}$ so that $h_i\le h' < h_{i+1}$.
Calculate
\[
  e_t = \tfrac{1}{4}
  \left[
    \cos(h'\pi/180\degree + 2) + 3.8
  \right]
\]
which is close to, but not exactly the same as, the eccentricity factor given
in table~\ref{table:hue}.

Hue quadrature is computed using the formula
\[
  H = H_i + \frac{100 e_{i+1} (h'-h_i)}{e_{i+1}(h'-h_i) + e_i (h_{i+1}-h')}
\]
and hue composition $H_c$ is computed according to $H$.  If $i=3$ and $H =
241.2116$ for example, then $H$ is between $H_3$ and $H_4$ (see
table~\ref{table:hue} above). Compute $P_L=H_4-H = 58.7884$; $P_R = H – H_3 =
41.2116$ and round $P_L$ and $P_R$ values to integers $59$ and $41$. Thus,
according to table~\ref{table:hue}, this sample is considered as having 59\%
of green and 41\% of blue, which is the $H$c and can be reported as 59G41B or
41B59G.
\end{step}

\begin{step}[6*]
Calculate the achromatic response
\[
  A\coloneqq p'_2 \cdot N_{bb}.
  \]
\end{step}

\begin{step}[7]
Calculate the correlate of lightness
\[
  J \coloneqq 100 {(A / A_w)}^{cz}.
\]
\end{step}

\begin{step}[8]
  Calculate the correlate of brightness
  \[
    Q \coloneqq \frac{4}{c} \sqrt{\frac{J}{100}} (A_w+4) F_L^{0.25}.
    \]
\end{step}

\begin{step}[9*]
Calculate the correlates of chroma ($C$), colorfulness ($M$), and saturation
  ($s$).
\begin{align*}
  t&\coloneqq \frac{50000/13 N_c N_{cb} e_t \sqrt{a^2 + b^2}}{u + 0.305},\\
  \alpha&\coloneqq t^{0.9} {(1.64 - 0.29^n)}^{0.73},\\
  C&\coloneqq \alpha \sqrt{\frac{J}{100}},\\
  M&\coloneqq C\cdot F_L^{0.25},\\
  s &\coloneqq 50 \sqrt{\frac{\alpha c}{A_w + 4}}.
\end{align*}
\end{step}

\subsection{Inverse model}

\begin{step}[1]
  Obtain $J$, $t$, and $h$ from $H$, $Q$, $C$, $M$, $s$.

  The input data can be different combinations of perceived correlates, that
  is, $J$ or $Q$; $C$, $M$, or $s$; and $H$ or $h$. Hence, the following
  sub-steps are needed to convert the input parameters to the parameters $J$,
  $t$, and $h$.
\end{step}

\begin{step}[1--1]
Compute $J$ from $Q$ (if input is $Q$)
\[
  J\coloneqq 6.25 \frac{cQ}{(A_w+4) F_L^{0.25}}.
\]
\end{step}

\begin{step}[1--2*]
Calculate $t$ from $C$, $M$, or $s$.
\begin{itemize}
  \item If input is $C$ or $M$:
    \begin{align*}
      C &\coloneqq M / F_L^{0.25} \:\text{if input is $M$}\\
      \alpha &\coloneqq \begin{dcases*}
          0 &if $J=0$,\\
          \frac{C}{\sqrt{J/100}}& otherwise.
      \end{dcases*}
    \end{align*}
  \item If input is $s$:
    \[
    \alpha \coloneqq {\left(\frac{s}{50}\right)}^2 \frac{A_w+4}{c}
    \]
\end{itemize}
Compute $t$ from $\alpha$:
\[
  t \coloneqq {\left(\frac{\alpha}{{(1.64 - 0.29^n)}^{0.73}}\right)}^{1/0.9}
\]
\end{step}

\begin{step}[1--3]
Calculate $h$ from $H$ (if input is $H$).
The correlate of hue ($h$) can be computed by using data in
table~\ref{table:hue} in the forward model.
Choose a proper $i\in\{1,2,3,4\}$ such that
$H_i \le H < H_{i+1}$. Then
\[
  h' = \frac{(H-H_i)(e_{i+1}h_i - e_i h_{i+1}) - 100 h_i e_{i+1}}{(H-H_i)(e_{i+1}-e_i) - 100 e_{i+1}}.
\]
Set $h = h' - 360\degree$ if $h' > 360\degree$, and $h=h'$ otherwise.
\end{step}

\begin{step}[2*]
Calculate $e_t$, $A$, $p'_1$, and $p'_2$
\begin{align*}
  e_t &= \tfrac{1}{4} (\cos(h\pi/180\degree + 2) + 3.8),\\
  A &= A_w  {(J/100)}^{1/(cz)},\\
  p'_1 &= e_t \tfrac{50000}{13} N_c N_{cb},\\
  p'_2 &= A / N_{bb}.
\end{align*}
\end{step}

\begin{step}[3*]
Calculate $a$ and $b$
  \begin{align*}
    \gamma &\coloneqq \frac{23 (p'_2+0.305) t}{23 p'_1 + 11 t \cos(h) + 108 t \sin(h)},\\
    a &\coloneqq \gamma \cos(h),\\
    b &\coloneqq \gamma \sin(h).
  \end{align*}
\end{step}

\begin{step}[4]
  Calculate $R'_a$, $G'_a$, and $B'_a$.
  \[
  \begin{pmatrix}
    R'_a\\G'_a\\B'_a
  \end{pmatrix}
  =
  \frac{1}{1403}
  \begin{pmatrix}
    460 & 451 & 288\\
    460 & -891 & -261\\
    460 & -220 & -6300
  \end{pmatrix}
  \begin{pmatrix}
    p'_2\\a\\b
  \end{pmatrix}.
  \]%
\end{step}

\begin{step}[5*]
Calculate $R_c$, $G_c$, and $B_c$,
  \[
  \rgb_c = \sign(\rgb'_a)
  \frac{100}{F_L} {\left(
    \frac{27.13 \abs{\rgb'_a}}{400 - \abs{\rgb'_a}}
    \right)}^{1/0.42}.
  \]
\end{step}

\begin{step}[6]
Calculate $R$, $G$, and $B$ from $R_c$, $G_c$, and $B_c$.
\[
  \rgb = \rgb_c / D_{\rgb}.
\]
\end{step}

\begin{step}[7]
Calculate $X$, $Y$, and $Z$. (For the coefficients of the inverse matrix, see
the note at the end of the appendix B of~\cite{cam16}.)
\[
\begin{pmatrix}X\\Y\\Z\end{pmatrix}
  = M_{16}^{-1}
\begin{pmatrix}R\\G\\B\end{pmatrix}.
\]
\end{step}

% \printbibliography{}
\bibliography{bib}{}
\bibliographystyle{plain}

\end{document}