%=========================================================================
% sec-opts-avx
%=========================================================================

\section{Vectorizing with SIMD Extensions}
\label{sec-opts-avx}

% Reason for optimization
\subsection{Reason for Optimization}

Many modern processors utilize a separate SIMD pipeline capable of
operating on wide (e.g., 256b, 512b) vector registers to achieve parallel
computation of multiple data elements. Special vector instructions in the
ISA can be used to schedule work onto these SIMD pipelines. In the case
of the Intel Xeon E5 2600-series installed on the totient compute nodes,
these vector instructions are a part of the Advanced Vector eXtensions
(AVX) of the x86 ISA.
\smallskip

One reason why effectively utilizing the SIMD pipeline is so important is
because it allows us to exploit data-level parallelism (DLP: same task on
different data elements) for workloads with regular control flow and
memory access patterns, such as the matrix multiplication in this
assignment. Explicitly, SIMD in this context allows us to:

\begin{itemize}
  \item amortize the overhead of fetching, decoding, and issuing the
    instruction across multiple data elements;
  \item apply computation to multiple data elements in parallel;
  \item and coalesce multiple scalar memory accesses into a single vector
    memory access.
\end{itemize}
\smallskip

Another reason is that most of the resources for high-throughput
floating-point computation is in the SIMD pipeline and leaving these
resources idle would mean we are already limiting our ideal performance
to a fraction of the system's potential. For example, each core in the
Xeon E5 has a 256b SIMD pipeline capable of supporting 8 floating-point
operations in parallel (assuming fused multiply-adds), whereas the scalar
pipeline only has 2 FPU units each capable of supporting a single
floating-point operation.
\smallskip

Although modern compilers have optimization passes to identify and
generate vector instructions automatically, this capability can be
limited compared to manually manually inserting vector
\emph{intrinsics}.
\medskip

% Details of optimization
\subsection{Details of Optimization}
\input{fig-opts-avx-vec}

As such, the goal of this optimization is to effectively utilize the SIMD
pipeline with AVX instructions. In order to do this, the first step is to
design a vectorization strategy for matrix
multiplication. Figure~\ref{fig-opts-avx-vec} outlines the
vectorization strategy used for this optimization.
\smallskip

If we consider the computations required to generate column {\tt{j}} of
matrix {\tt{C}}, we can see that all elements in column {\tt{k}} of matrix
{\tt{A}} need to be multiplied by $B_{kj}$. With this insight, we can
write the equation for computing a vector of elements in column {\tt{j}} of
matrix {\tt{C}} as follows:
\[
\{C_{0j},...,C_{Nj}\} = \sum_{k=0}^{N}\{A_{0k},...,A_{Nk}\}*B_{kj}
\]
\smallskip

By using vector registers to represent multiple elements of a given
column, we are able to vectorize computation across multiple elements
within a column of the output matrix.
\smallskip

The pseudo-assembly for computing one column of a block in the output
matrix is shown below:
\smallskip

\begin{verbatim}
    load.v  vr1, 0(c_addr) // vector load {C_0j,...,C_Nj} (partial product)
_loop:
    load.v  vr2, 0(a_addr) // vector load {A_0k,...,A_3k}
    load    r2,  0(b_addr) // load B_kj
    set.v   vr3, r2        // broadcast B_kj to vector register
    mul.v   vr4, vr2, vr3
    add.v   vr1, vr4, vr1
    addi    a_addr, inc    // pointer bump for A
    addi    b_addr, inc    // pointer bump for B
    br      _loop          // loop for N iterations
    store.v vr1, 0(c_addr) // vector store {C_0j,...,C_Nj}
\end{verbatim}
\smallskip

An alternative strategy would be to vectorize computation across
multiple elements within a \emph{row} of the output matrix. The challenge
with this approach is that since we would need to load multiple elements
within a row of matrices {\tt{B}} and {\tt{C}}, and since the matrices
are column-major in memory, we would have a stride of {\tt{N}} instead of
unit-stride as before. Not only would this be undesirable for cache
locality, it means we would be unable to utilize efficient vector loads,
which can only load elements that are consecutive in memory. However, in
order to evaluate the impact of regular vs. irregular memory accesses, we
have submitted both strategies for this assignment. These
implemementations are named {\tt{dgemm\_avx\_regular.c}} and
{\tt{dgemm\_avx\_irregular.c}}, respectively.
\smallskip

In addition to vectorizing matrix multiplication, AVX also has support
for fused floating-point multiply-adds (FMAs). Instead of having separate
instructions for the multiply and add in the pseudo-assembly above, FMAs
allow us to execute these operations as a single instruction. This
essentially doubles the throughput of floating-point operations in the
SIMD pipeline.
\smallskip

So far we have been assuming matrix dimensions that are evenly divisible
by 4, but there are some non-trivial complications that arise when this
is not the case. First, we cannot use standard vector memory operations
because they must always access \emph{256b-aligned addresses in
  memory}. We can always enforce this alignment during memory allocation
for the first column of a matrix, but if the dimensions are not evenly
divisible by the vector width, all subsequent columns are not guaranteed
to be aligned. To address this, we use \emph{unaligned} vector
memory operations which allow accesses to non-256b-aligned addresses, but are
not as efficient as the standard variants. Second, even with unaligned
vector memory operations, there is still the corner case when we want to
vector load the last elements in a column (i.e., the last 3 elements in a
column left to compute, but we vector load in groups of 4). We do not
want to modify any elements beyond the current column we are computing
lest we run the risk of storing junk data to the next column. To address
this, we use \emph{masked} vector memory operations that can specify which of
the 4 elements in memory should be accessed (i.e., only load the first 3
elements starting from the base address, instead of 4). However, masked
vector memory operations are even less efficient than the unaligned
variants.
\smallskip

A conservative approach would be to always calculate the mask and use the
masked vector memory operations. This would be slow, but would guarantee
correctness. A more aggressive approach would be to prioritize these
different types of vector memory operations in the order of highest efficiency
whenever possible:
\smallskip

\begin{itemize}
  \item Standard: for matrix dimensions divisible by 4
  \item Unaligned: for any matrix dimensions, when we are \emph{not}
    computing the last elements in a column
  \item Masked: for any matrix dimensions, when we are computing the last
    elements in a column
\end{itemize}
\medskip

% Results and analysis
\subsection{Results}
\input{fig-opts-avx-results}

We evaluate both the regular and irregular memory access variants of the
vectorizing optimization with FMAs and support for any matrix dimension
using masked vector memory operations. In order to quantify the benefit
of manual-vectorization over auto-vectorization, we show the performance
of the provided blocked implementation using the {\tt{-xAVX}} compiler
flag. The results of using a combination of manual- and
auto-vectorization were also collected. All results are shown in
Figure~\ref{fig-opts-avx-results}.
\smallskip

The regular variant showed the better speedup of ~3x over the naive
blocked implementation. In contrast, the irregular variant had a slowdown
of roughly ~2x over the same baseline, highlighting the importance of
prioritizing desirable cache access patterns as well as efficient vector
memory operations. In addition, we can see that auto-vectorization is
significantly worse than manual-vectorization, but combining both
techniques outperforms either. This makes sense, since there are still
opportunities for vectorization that are not exploited with
manual-vectorization that is easier for the compiler to optimize.
\smallskip

Since we are using doubles (64b) for data elements and the SIMD pipeline
is 256b wide, we know we can fit 4 elements per vector register. In the
ideal case where the matrix dimension is evenly divisible by 4, we are
parallelizing computation over 4 elements of the output matrix. Coupled
with the use of FMAs which double the throughput of floating-point
operations in the SIMD pipeline, the ideal speedup should be ~8x. There
are several factors that prevent us from reaching this limit. For one,
the ideal speedup does not take into account the cache misses and
thrashing that occurs in practice. There is also the overhead from
copying scalar registers to vector registers, as well as the mask
calculation for masked vector memory operations. The overhead from
conditional blocks for prioritizing different types of vector memory
operations is non-trivial as well.

%\clearpage


\subsubsection{\stid{3.13} CLOVER} \label{subsubsect:clover}
Mathematical libraries are powerful tools to make better use of Exascale
architectural features and are central for application projects to efficiently
exploit the available computing power. The high-level objective of CLOVER is to
provide scalable, portable numerical algorithms that facilitate efficient
application simulations on Exascale computers. With the intention of generating synergies
by facilitating vivid cooperation among the distinct project focus efforts
and expert knowledge transfer, CLOVER was designed as a merger of the heFFTe, SLATE,
and Ginkgo projects, each being complementary
in focus but similar in the need for hardware-specific algorithm design
expertise: SLATE focuses on Exascale-capable dense linear algebra
functionality; heFFTe’s scope is providing robust and fast calculation for 2D
and 3D FFT routines; Ginkgo delivers production-ready, preconditioned iterative solvers for
GPU-accelerated systems. Together, these projects form a robust ecosystem of numerical
base functionality for Exascale computers.
\newpage


\chapter{PCA on spectral data}
\label{ch:spectral-PCA}

\begin{wrapfigure}{o}{0.7\textwidth}
    \includegraphics[scale=0.4]{workflow1.png}
\end{wrapfigure}

In this lesson we will explore the capabilities of \mutation\ for principal component analysis (PCA) on spectroscopy data. As usual, we will use the Liver Spectroscopy dataset. Connect \widget{Datasets} to the \widget{PCA} widget, choose the first 5 principal components and then connect \widget{PCA}'s default output, ``Data'', into the \widget{Scatter Plot}.

We see that the first two principal components separate majority compounds in that part of the tissue well.

\begin{figure*}[h]
\centering
\infinitewidthbox{
  \stackinset{r}{-0.35\linewidth}{t}{+0.1\linewidth}
  {\includegraphics[scale=0.4]{scatterplot.png}}
  {\includegraphics[scale=0.4]{pca.png}}
  \hspace{6cm}
  }
\caption{We chose not to normalize variables in \widget{PCA}. Why?}

\end{figure*}

\begin{wrapfigure}{o}{0.8\textwidth}
  \includegraphics[width=0.8\textwidth]{components.png}%
  \caption{The curve under the cursor is highlighted. A tooltip will appear after some time. If clicked, the curve will be selected.}
\end{wrapfigure}

To see what different principal components represent, connect \widget{PCA’s} ``Components'' output (be careful, \widget{PCA} has 4 outputs) into \widget{Spectra}. Wondering which principal component is highlighted in the following screenshot? Wait for the tooltip...

\clearpage

Let's extend our workflow. If we connect the \widget{PCA} (``Transformed Data'' output) to \widget{Spectra}, we can see each transformed spectrum on a line plot. As we can see, some classes have outliers.

\begin{wrapfigure}{o}{0.9\textwidth}
    \includegraphics[scale=0.4]{workflow2.png}
\end{wrapfigure}

To find out more about a particular outlier, we can select it in the \widget{Spectra} widget: move your mouse cursor to a curve---it will be highlighted—-and click it. The selected curve changes to a dotted line and is sent to the output.

Then, connect the \widget{Spectra} widget to the \widget{Scatter Plot} and the \widget{Spectra (1)} widgets' ``Data Subset'' inputs; these widgets will need two inputs to function as shown, the subset coming from the selection in \widget{Spectra} and the whole data set. Now we can see the selected outlier in the original space (\widget{Spectra (1)} widget) and in the space of principal components (\widget{Scatter Plot}), both in the context of all spectra from the data set.

\begin{figure*}[h]
  \centering
  \begin{tabular}{ c  c }
      \includegraphics[scale=0.4]{selection-spectra.png}  & \includegraphics[scale=0.4]{subset-spectra.png} \\
      & \includegraphics[scale=0.4]{subset-scatterplot.png}
  \end{tabular}
  \vspace{0.3cm}
  \caption{The selected spectrum's curve on the left is drawn with a dashed line and the corresponding original spectrum is highlighted on the right. The \widget{Scatter Plot} shows the position of the selected spectrum in the PCA space.}
\end{figure*}


%
%$Id: utilIntro.tex,v 1.2 2005-07-06 14:11:27 kbk Exp $
%

\section{Utilities}\label{sec:util}

\subsection{Introduction}

In this section, different utility modules and routines are assembled,
such as the {\tt time} module (see {\tt time.F90}), keeping track of all time
calculations, the {\tt mtridiagonal} module with a Gaussian solver for
systems of equations with tri-diagonal matrices (see {\tt
tridiagonal.F90}), and the {\tt eqstate} module (see {\tt
eqstate.F90}) with different versions of the equation of state.

Also discussed are advection and diffusion routines, such as {\tt
diff\_center()} and {\tt adv\_center()} for variables located
at the centers of the grid cells, i.e.\ in general mean flow
variables.


%\documentclass[10pt, conference, compsocconf]{IEEEtran}
\documentclass[a4paper,11pt]{article}

\usepackage{soul}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{color}
\usepackage{graphicx}
\usepackage{setspace}
\usepackage{hyperref}

\pdfinfo{%
  /Title    (Lab 1: Sieve of Eratosthenes)
  /Author   (Max Clive, Hawk Weisman, Alden Page, Ryan Cambier)
  /Subject  (CS 220 Programming Languages Lab)
  /Keywords (Programming languages)
}

%\pdfpagewidth 8.5in %
%\pdfpageheight 11.0in %

%\addtolength{\oddsidemargin}{-.50in} %.875in
%\addtolength{\evensidemargin}{-.50in} %.875in
%\addtolength{\textwidth}{1.in} %1.75in
%\addtolength{\topmargin}{-.875in} %.875in
%\addtolength{\textheight}{1.in} %1.75in

%opening

\begin{titlepage}

\title{Computer Science 220 \\[20pt]
Programming Languages Concepts\\ [20pt]
\textbf{Lab Assignment 1: Sieve of Eratosthenes}}
\author{Group NullPointerException: \\ Max Clive, Hawk Weisman, Alden Page, Ryan Cambier}
\date{September 13, 2013 }

\end{titlepage}

\usepackage{listings}
\usepackage{color}

\definecolor{dkgreen}{rgb}{0,0.6,0}
\definecolor{gray}{rgb}{0.5,0.5,0.5}
\definecolor{mauve}{rgb}{0.58,0,0.82}

\lstset{frame=tb,
  language=Java,
  aboveskip=3mm,
  belowskip=3mm,
  showstringspaces=false,
  columns=flexible,
  basicstyle={\small\ttfamily},
  numbers=none,
  numberstyle=\tiny\color{gray},
  keywordstyle=\color{blue},
  commentstyle=\color{dkgreen},
  stringstyle=\color{mauve},
  breaklines=true,
  breakatwhitespace=true
  tabsize=3
}

\begin{document}

\maketitle

\section{Comparing Java and C}

		Overall, the implementations of the algorithm didn't differ much between either language. The most notable difference is the length of the programs – C's minimal syntax allows for a more concise program, although it comes at the cost of less built-in error handling and more difficult debugging. Theoretically, the C version of the same program should run significantly faster, but speed isn't terribly relevant in a project of this nature and scale.
	With knowledge of C's “gotchas” (e.g. accessing outside of the boundaries of arrays, dereferencing null pointers, various other pointer-related disasters,) it is possible to avoid some of the dangers that C is infamous for.
	In contrast, while Java's design attempts to force the user to consider every possible contingency through error handling and use approved design patterns, this robustness and reliability comes at the cost of much more cluttered code. C allows the developer to just “get it done,” trusting he or she to insert as much complexity as is necessary, no matter what the consequences that that may entail.

\section{Java Implementation of Sieve}

\begin{lstlisting}

import java.util.Scanner;

public class NullPointerException_Sieve {

	private final int MAX_NUM = 50000;
	private boolean[] primes = new boolean[50001];
	private int upper, lower;
	Scanner scan = new Scanner(System.in);

	/**
	Constructor for Sieve
	*/
	public NullPointerException_Sieve() {
		primes[0] = false;
		primes[1] = false;
		upper = MAX_NUM;
		lower = 1;
		for (int i = 1; i < primes.length; i++){
			primes[i] = true;
		}
	}

	/**
	Implements the Sieve of Eratosthenes algorithm
	*/
	public void processSieve(){
		primes[1] = false;						// 1 is not a prime number
		for(int p = 2; p < 50000;) {
			for(int count = 2; count * p < 50000; count++) {
				primes[count * p] = false;
			}
			while(p < 50000 && primes[++p] == false);	// fast forward to the next prime number
		}
	}

	/**
	Shows the set of sexy pairs
	*/
	public void showPrimes() {
		System.out.printf("Here are all of the sexy prime pairs in the range %d to %d \n", lower, upper);
		int count = 0;
		for (int i = lower; i <= upper; i++) {
			if (primes[i] == true && i-6 > 0 && primes[i-6] == true) {
				System.out.printf("%d and %d \n", i, (i-6));
				count++;
			}
		}
		System.out.printf("There were %d sexy prime pairs displayed between %d and %d.\n", count, lower, upper);
	}

	/**
	gets lower and upper boundaries
	*/
	public void getBoundaries() {
		System.out.println("Please enter a lower boundary and an upper boundary and I will print all of the sexy prime pairs between those boundaries.");
		do {
			while (!(1 < upper && upper < 50000)) {
				System.out.print("Please enter the upper boundary (must be between 1 and 50000):");
				try {
					upper = Integer.parseInt(scan.nextLine());
				}
				catch (Exception e) {
					System.out.println("NaN");
				}
			}
			while (!(1 < lower && lower < 50000)) {
				System.out.print("Please enter the lower boundary (must be between 1 and " + upper + "):");
				try {
					lower = Integer.parseInt(scan.nextLine());
				}
				catch (Exception e) {
					System.out.println("NaN");
				}
			}
		} while (!(lower <= upper));
	}
}
\end{lstlisting}

\section{Java Test Program}

\begin{lstlisting}

public class NullPointerException_SieveTest {
	public static void main(String argv[]) {
	NullPointerException_Sieve steve = new NullPointerException_Sieve();
	steve.processSieve();
	steve.showPrimes();
	steve.getBoundaries();
	steve.showPrimes();
	}
}

\end{lstlisting}

\section{C Implementation of Sieve}

\begin{lstlisting}

#include <stdio.h>
typedef struct Bounds Bounds;

//should move function declarations to a .h file
void processSieve();
int boundSizeCheck(int endpoint);

struct Bounds {
    int lowBound;
    int highBound;
};

Bounds b = {0,0};

void getBoundaries() {
    printf("Enter the lower bound: ");
    scanf("%d", &b.lowBound);
    printf("Enter he upper bound: ");
    scanf("%d", &b.highBound);

    if (boundSizeCheck(b.lowBound)) || (boundSizeCheck(b.highBound)){
        printf("Please enter the boundaries again.")
        getBoundaries();
    }
}

//Make sure input is of reasonable size
int boundSizeCheck(int bound) {
    if (bound > 50000 || bound < 1){
        printf("Inputs must be below 50000 and above 0.\n");
        return 1;
    }
    else return 0;
}

void processSieve() {
    //p is the current prime number being evaluated
    int p = 2;
    int i, j;
    //Populate our array with numbers
    for (i = 0; i < ARRAYSIZE; i++){
        primes[i] = i;
    }

    //iterate through every element
    for (i = p; p < ARRAYSIZE; i++){
        //if the element is prime, cross off its multiples
        if (primes[i]){
            for (j = i + p; j < ARRAYSIZE; j = j + p){
                primes[j] = 0;
            }
        }
        p++;
    }
}

\end{lstlisting}

% begin typing

\end{document}


%!TEX root = ../dissertation_vkslm.tex

\chapter{Conclusion and Future Works}\label{ch:conclusion}

In this work a method to produce synthetic offline signatures by means of a supervised learning task has been presented. We propose a Fully Convolutional Neural Network to learn an end-to-end mapping of online manuscripts to the static domain, taking advantage of the data present in the IRONOFF dataset during the training phase of the Neural Network.

We show that, in contrast to what has already been proposed, it is possible to model the "online to offline signature" as a learning from data task. Our Deep Neural Network model learns how the online biometric data must be used to build the grayscale signature image.  The use of synthetically generated signatures offers verification performance similar to those observed by using real signatures. We also show that the synthetic signatures generated with our proposed method present high discriminative power when used to increase the enrollment set under the skilled forgeries scenario.

In order to evaluate our proposed method, we evaluated our proposed method by means of machine-oriented validations. We used a state-of-the-art automatic signature verifier to assess that similar results were obtained with both the real and our proposed method synthetic signatures. We found that our proposed method produces synthetic signatures comparable to real ones and when used to increase amount of training samples the system's EER decreases from 10.26\% to 9.74\% on the random forgeries scenario and from 21.55\% to 19.17\% for skilled forgeries.

Future work can explore the optimization of the hyper-parameters of the FCN (such as the number of layers, number of neurons per layer) since these hyper-parameters were fixed during the experiments in the present work. Besides, we intend to explore the combination of real online and synthetically generated offline signatures using the proposed method, when only the online information is available, towards improved recognition results on a dynamic signature verifier.

It is also possible to explore recent advancements on Generative Adversarial Networks \cite{goodfellow2014generative} such as the Image-to-image translation \cite{isola2016image} method to convert the online samples to static images.

Another improvement to the current work is the integration of other dynamic features in addition to the pressure on the input of the network, such as the velocity. Moreover, one could also design a model to synthesize offline signatures with bigger resolution.


\section{Global Fit Stability}
%\label{sec:globalFitStability} % uncomment if label used.
\subsection{Signal Injection}
%\label{subsec:globalFitStability:SignalInjection} % uncomment if label used.
Since to produce the background fit our full signal range is fitted, if our signal region contains a signal our background fit will be modified compared to the case where the signal region is purely background, referred to as the fit stability. As the dijet fit functions are motivated by theory for the QCD dijet distribution, in particular that they are smooth and monotonically decreasing, the effect on the fit should be negligible when injecting a signal with a width small compared to the full fit range. However, it is important to verify that this is the case.

To measure the effect of signal contamination on our background fit, the following method has been used:

\begin{itemize}
    \item Take nominal background fit from fitting data with 5param dijet function.
    \item Add signal to nominal fit to get signal+background fit.
    \item Generate 1,000 pseudoexperiments from signal+background fit.
    \item Loop over every pseudoexperiment:
    \begin{itemize}
        \item generate new background fit (bkg$_{PE}$ from pseudoexperiment).
        \item calculate excess events per bin by subtracting bkg$_{PE}$.
    \end{itemize}
    \item Get average \& standard deviation of all pseudoexperiments excess events per bin.
    \item Look at bins around resonance ('around' chosen such that $\approx$50\% of the total events in the signal are considered, $\approx$ rather than exact since the bins are quite wide \& signal falls rapidly. This roughly corresponds to the region found by BumpHunter at $\approx$3$\sigma$).
    \item Compare excess events in bins around resonance to injected events. (Importantly, retrieved events \& injected events are the retrieved \& injected events in this region around resonance, not over full fit).
    \item Do same with subtracting nominal fit instead of new fit to compare.
\end{itemize}

A table showing how many injected events correspond to a BumpHunter significance of 1, 2 and 3 $\sigma$ is shown in Table \ref{tab:BHSignifcanceStringInjection} to help determine how significant a signal must be injected before the effect of the fit stability is relevant. The results for number of average retrieved events for an injected number of signal events  for a 7.0, 7.5, 8.0, 8.5 and 9.0 TeV string signal injections are shown in Figures \ref{fig:StringSignalInjectionFitStabilityStudyMs7.0TeV}-\ref{fig:StringSignalInjectionFitStabilityStudyMs9.0TeV} respectively.

\begin{table}[]
    \tiny
    \begin{center}
%        \hspace*{-4cm}
        \begin{tabular}{l|lll|lll|lll|lll|lll|}
            \toprule
            \midrule
            String Scale {[}TeV{]}   & \multicolumn{3}{c|}{7.0}             & \multicolumn{3}{c|}{7.5}             &
\multicolumn{3}{c|}{8.0}             & \multicolumn{3}{c|}{8.5}             & \multicolumn{3}{c|}{9.0}             \\
            \midrule
            Resonance Bins {[}GeV{]} & \multicolumn{3}{c|}{{[}6047-7188{]}} & \multicolumn{3}{c|}{{[}6407-7610{]}} & \multicolumn{3}{c|}{{[}6918-8208{]}} & \multicolumn{3}{c|}{{[}7326-8685{]}} & \multicolumn{3}{c|}{{[}7756-9191{]}} \\
            Bumphunter Significance  & 1          & 2          & 3          & 1          & 2          & 3          & 1          & 2          & 3          & 1          & 2          & 3          & 1          & 2          & 3          \\
            Injected Events          & 23.95      & 34.35      & 44.36      & 15.62      & 23.04      & 29.78      & 9.844      & 14.09      & 18.52      & 6.353      & 9.233      & 12.25      & 0.413      & 6.165      & 8.275      \\
            Cross-Section {[}fb{]}   & 0.4984     & 0.7147     & 0.9231     & 0.3067     & 0.4525     & 0.5848     & 0.2006     & 0.2871     & 0.3775     & 0.1273     & 0.1850     & 0.2454     & 0.0083     & 0.1239     & 0.1663 \\
            \midrule
            \bottomrule
            \end{tabular}
        \end{center}
    \caption{Number of injected events within bins around the resonance corresponding to a BumpHunter significance of 1, 2 and 3 for String signals with String Scale 7.0, 7.5, 8.0, 8.5 and 9.0}
    \label{tab:BHSignifcanceStringInjection}
\end{table}
\begin{figure}
    \centering
    \includegraphics[trim={0cm 0cm 1.6cm 1cm},clip,width=1.0\linewidth]{figures/app-GlobalFitStability/injectionFitStabilityStringScale7000.pdf}
    \caption{Signal stability for a signal injection of a String sample with String Scale 7.0 TeV}
    \label{fig:StringSignalInjectionFitStabilityStudyMs7.0TeV}
\end{figure}
\begin{figure}
    \centering
    \includegraphics[trim={0cm 0cm 1.6cm 1cm},clip,width=1.0\linewidth]{figures/app-GlobalFitStability/injectionFitStabilityStringScale7500.pdf}
    \caption{Signal stability for a signal injection of a String sample with String Scale 7.5 TeV}
%    \label{fig:StringSignalInjectionFitStabilityStudyMs7.5TeV} % uncomment if label used.
\end{figure}
\begin{figure}
    \centering
    \includegraphics[trim={0cm 0cm 1.6cm 1cm},clip,width=1.0\linewidth]{figures/app-GlobalFitStability/injectionFitStabilityStringScale8000.pdf}
    \caption{Signal stability for a signal injection of a String sample with String Scale 8.0 TeV}
%    \label{fig:StringSignalInjectionFitStabilityStudyMs8.0TeV} % uncomment if label used.
\end{figure}
\begin{figure}
    \centering
    \includegraphics[trim={0cm 0cm 1.6cm 1cm},clip,width=1.0\linewidth]{figures/app-GlobalFitStability/injectionFitStabilityStringScale8500.pdf}
    \caption{Signal stability for a signal injection of a String sample with String Scale 8.5 TeV}
%    \label{fig:StringSignalInjectionFitStabilityStudyMs8.5TeV} % uncomment if label used.
\end{figure}
\begin{figure}
    \centering
    \includegraphics[trim={0cm 0cm 1.6cm 1cm},clip,width=1.0\linewidth]{figures/app-GlobalFitStability/injectionFitStabilityStringScale9000.pdf}
    \caption{Signal stability for a signal injection of a String sample with String Scale 9.0 TeV}
    \label{fig:StringSignalInjectionFitStabilityStudyMs9.0TeV}
\end{figure}

It can be seen that the effect of fit stability upon injection for all String samples investigated is negligible for signals large enough to produce up to and above a BumpHunter significance of 3 $\sigma$. The fit stability is worse (but still negligible) for signals with a resonance at lower $m_{jj}$ for two reasons, being that the effect is larger for a higher number of injected events while at lower $m_{jj}$ more events are needed to be injected to produce a significant signal, and also that for the same number of injected events the effect is larger at lower $m_{jj}$.

\subsection{Spurious Signal}
%\label{subsec:globalFitStability:SpuriousSignal} % uncomment if label used.

In addition to fit stability under signal injection as investigated in the previous section, it is important to verify that the fit is stable under no signal injection, i.e. that on average the number of retrieved events is consistent with 0. This has been investigated using the same method as the previous section, but instead injecting 0 signal. Then, the number of retrieved events within a region of 0.1 TeV and 1 TeV is measured, to determine that the fit is stable under no signal injection both in a small region and wide region.

The results of this spurious signal fit stability test are shown in Figures \ref{fig:SpuriousSignalInjectionFitStabilityStudy0.1TeVRegion} and \ref{fig:SpuriousSignalInjectionFitStabilityStudy1.0TeVRegion} for the 0.1 TeV and 1 TeV region respectively. It can be seen that the number of retrieved events is consistent with 0 in both cases all across the $m_{jj}$ range. Discontinuity/non-smoothness at very low $m_{jj}$ is purely because of the region investigated going below the minimum $m_{jj}$ cut.

\begin{figure}
    \centering
    \includegraphics[trim={0cm 0cm 2cm 1cm},clip,width=1.0\linewidth]{figures/app-GlobalFitStability/spuriousSignalFitStabilityWidth100.pdf}
    \caption{Signal stability for no injected signal looking at a region of width 0.1 TeV}
    \label{fig:SpuriousSignalInjectionFitStabilityStudy0.1TeVRegion}
\end{figure}
\begin{figure}
    \centering
    \includegraphics[trim={0cm 0cm 2cm 1cm},clip,width=1.0\linewidth]{figures/app-GlobalFitStability/spuriousSignalFitStabilityWidth1000.pdf}
    \caption{Signal stability for no injected signal looking at a region of width 1.0 TeV}
    \label{fig:SpuriousSignalInjectionFitStabilityStudy1.0TeVRegion}
\end{figure}


\documentclass{article}
\usepackage{afterpage}
\usepackage{float}
\usepackage{longtable}
\usepackage{graphicx}
\usepackage{pdflscape}
\usepackage[numbers,sort&compress]{natbib}
\usepackage{psfrag}

\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{graphicx}
%\usepackage{nicefrac}
\usepackage{graphicx}
\usepackage{caption}
% \usepackage{subcaption}
\usepackage{subfigure}
% \usepackage{algorithm}
% \usepackage{paralist}
% % \usepackage[geometry]{ifsym}
\usepackage{rotating}
\usepackage{setspace}
\newcommand{\uu}[1]{\boldsymbol #1}
\usepackage{listings}
\usepackage{xcolor}
\usepackage{subfigure}
\usepackage{fullpage}
\lstset{language=C++,
                keywordstyle=\color{blue},
                stringstyle=\color{red},
                commentstyle=\color{green},
                morecomment=[l][\color{magenta}]{\#}
}
\doublespace
\begin{document}
\section{Approximating $F+C^T(M+X)^{-1}C$}

Using the result in [Elman,....] we approximate
\begin{equation} \label{eq:fluid}
A = F+C^T(M+X)^{-1}C \approx F+Q_s=B,
\end{equation}
were $Q_s$ is a scaled vector mass matrix. Solving the penalised eigenvalue
problem
$$Bx = \lambda Ax,$$
produces the following eigenvalue plots.
\begin{figure}[h]
\begin{center}$
\begin{array}{cc}
\includegraphics[width=0.5\textwidth]{FLUIDkappa=10_nu_m=10_nu=1_n=2}&
\includegraphics[width=0.5\textwidth]{FLUIDkappa=10_nu_m=10_nu=1_n=4}\\
\includegraphics[width=0.5\textwidth]{FLUIDkappa=10_nu_m=10_nu=1_n=8}&
\includegraphics[width=0.5\textwidth]{FLUIDkappa=10_nu_m=10_nu=1_n=16}
\end{array}$
\end{center}
\caption{Eigenvalue plot for various values of n}
\label{pics:blablabla}
\end{figure}
\begin{figure}[h]
\begin{center}$
\begin{array}{cc}
\includegraphics[width=0.5\textwidth]{FLUIDkappa=100_nu_m=10_nu=1_n=2}&
\includegraphics[width=0.5\textwidth]{FLUIDkappa=100_nu_m=10_nu=1_n=4}\\
\includegraphics[width=0.5\textwidth]{FLUIDkappa=100_nu_m=10_nu=1_n=8}&
\includegraphics[width=0.5\textwidth]{FLUIDkappa=100_nu_m=10_nu=1_n=16}
\end{array}$
\end{center}
\caption{Eigenvalue plot for various values of n}
\label{pics:blablabla}
\end{figure}

\newpage
\section{Approximating $M+X+CF^{-1}C^T$}

Using the result in [Elman,....] we approximate
\begin{equation} \label{eq:magnetic}
A = M+X+CF^{-1}C^T \approx M+X+X_s=B,
\end{equation}
were $X_s$ is a scaled vector mass matrix. Solving the generalised eigenvalue
problem
$$Bx = \lambda Ax,$$
produces the following eigenvalue plots.
\begin{figure}[h]
\begin{center}$
\begin{array}{cc}
\includegraphics[width=0.5\textwidth]{MAGkappa=1_nu_m=10_nu=1_n=2}&
\includegraphics[width=0.5\textwidth]{MAGkappa=1_nu_m=10_nu=1_n=4}\\
\includegraphics[width=0.5\textwidth]{MAGkappa=1_nu_m=10_nu=1_n=8}&
\includegraphics[width=0.5\textwidth]{MAGkappa=1_nu_m=10_nu=1_n=16}
\end{array}$
\end{center}
\caption{Eigenvalue plot for various values of n}
\label{pics:blablabla}
\end{figure}
\begin{figure}[h]
\begin{center}$
\begin{array}{cc}
\includegraphics[width=0.5\textwidth]{MAGkappa=10_nu_m=10_nu=1_n=2}&
\includegraphics[width=0.5\textwidth]{MAGkappa=10_nu_m=10_nu=1_n=4}\\
\includegraphics[width=0.5\textwidth]{MAGkappa=10_nu_m=10_nu=1_n=8}&
\includegraphics[width=0.5\textwidth]{MAGkappa=10_nu_m=10_nu=1_n=16}
\end{array}$
\end{center}
\caption{Eigenvalue plot for various values of n}
\label{pics:blablabla}
\end{figure}

\section{Discussion}

From the figures, we note that the eigenvalues computed when using the
approximation given in (\ref{eq:magnetic}) seem to spread out as the mesh size,
$n$, gets bigger. However, for the approximation (\ref{eq:fluid}) the eigenvalues seem to be
clustered nicely. There appears to be a single eigenvalue that is about 1.2 for
$\kappa = 10$ and 2 for $\kappa = 100$ that is not clustered. This single
eigenvalue does not, however, seem to increase dramatically as the mesh size
increases.

\end{document}


\documentclass[10pt]{article}
\usepackage{../inc/style}
\begin{document}
% ---------------------------------------------------------------------
\title{Calculus extended}
\subsection*{Language specifications}
\subsubsection*{Syntax}
File format is similar to M3. There are 4 sections: sources, maps declarations, queries and explicit triggers. The source queries and trigger definitions are the same as in M3.
The maps are defined as:\ul
\item {\tt\small DECLARE MAP map[indices:types] := expr;} where expression is a calculus expression. Map references can appear in the expression (including self-reference). Maps are intentional by default.
\item {\tt\small DECLARE MAP map[indices:types] : type;} declares an unmanaged map, that has no associated triggers. The user can the define extra triggers to compute this map.
\ule
We extend the expressions language with:\ul
\item {\tt\small AggMin([indices], expr)}, {\tt\small AggMax([indices], expr)} that return the minimal resp. maximal value of expression or 0 if there is no such expression exists.
\ule
We add new statements (in triggers):\ul
\item {\tt\small CALL trigger(values) IN expression;} where the IN expression part can be omitted if it is 1. values are constants or variables bound by the right hand-side expression.
\ule
The incremental computation of each map is then computed (M3) before it is transformed to imperative version with explicit loops in the target language.

\subsubsection*{Semantics}
Maps support recursive declaration. Trigger for different maps will be aggregated in a single trigger for a particular event. Triggers calls are passed through a queue (to keep consistent behavior with distributed version). This implies that whenever an event happen all rule are traversed once, matching rules are called and recursive events are added to the queue. Then the next event from the queue is being processed until the queue is empty. Desirable properties we want to achieve (give strong intuition/proof):\ul
\item Avoid synchronization between add operations on maps (in particular for computing fixpoints)
\item Avoid stack overflows due to recursion (this is dealt with the events/calls queue)
\item Avoid recursion if the value is not changed (or changed below some relative threshold)
\ule

\subsection*{Examples}
\subsubsection*{Problem 1: betweenness centrality}
Let our fact table be $edge(x,y)$ we want to compute the \href{http://en.wikipedia.org/wiki/Betweenness_centrality}{betweenness centrality} $g(v)$ of graph nodes $v$, we apply the following rules:
\[\begin{array}{rcl}
edge[x,y] & := & \text{\it storage of input stream} \\
path[x,y,len] & := & \exists(edge[x,y]) \times (len\hat= 1) +  \exists(edge[x,z]) \times \exists(path[z,y,l]) \times (len\hat= 1+l) \times (x\ne y)\\
path_v[x,y,v,len] & := & \exists(path[x,v,l_1]) \times \exists(path[v,y,l_2]) \times (len\hat= l_1+l_2) \times (x\ne y) \\
centrality[v] & := & \exists(path[x,y,m]) \times (\exists(path[x,y,s] \times (s<m)) = 0) \times \left(\dfrac{{\rm AggSum}([], path_v[x,y,v,m])}{path[x,y,m]}\right)
\end{array}\]

By adding the condition $(x\ne y )$ in the $path$ definition, we prevent cycles.

\subsubsection*{Problem 2: PageRank}
The iterative method of \href{http://en.wikipedia.org/wiki/PageRank#Iterative}{PageRank} is defined for $N$ pages with a matrix $M=(K^{-1} A)^T$ where $A$ is the adjacency matrix of the graph, $K$ the diagonal matrix with out-degrees in diagonal. We compute \[R(t+1)=d\cdot M\cdot R(t)+\dfrac{1-d}{N}{\bf 1} \qquad \text{with {\bf 1} a column vector of 1 and }R(0)={\bf 1}\cdot \frac{1}{n}\]
The issues with the matrix model is that all computation are done synchrnously.

\textbf{Naive version:} To avoid explicit synchronization, we have 2 solutions: maintaining versions in the database or normalizing $|R|=1$ after every computation.
\[\begin{array}{rrl}
node[x] &:=& \text{\it input stream} \in\{0,1\} \\
edge[x,y] &:=& \text{\it input stream, adjacency matrix} \\
weight[x] &:=& node[x] \times (w_0\hat=weight[x]) \times \left( w_0 + (w_1\hat=nw) \times \left(
\dfrac{|w_1 - w_0|}{w_1+w_0} > {\rm threshold}\right) \times (w_1-w_0) \right) \\ \\
&& \text{where } nw= {\rm AggSum}([], \dfrac{edge[y,x] \times weight[y]}{{\rm AggSum}([],edge[y,z])}) \times d + \dfrac{1-d}{{\rm AggSum}([],node[v])}\\
\end{array}\]
The shortcomings with this approach are the non-preservation of global weight and injection of initial coefficient. The $d$ weighting should mitigates this issue (but not sure at all !!). We also must ensure that we don't call recursively if the value did not change (encode this with threshold in map declaration or in another function?).

\textbf{Clock join:} One possible idea to virtually execute the program synchronously is to have a clock stream and a timestamp attribute for all maps. When a clock tick is inserted, the next iteration can be computed (join $data \times tick$); when the tick is removed, the associated data can be removed from the map. Issues:\ul
\item Deletion trigger of weight must be \underline{overridden} to only remove data (and avoid recursion).
\item How to know that all the data at a tick has been fully computed ?
\ule
\[\begin{array}{rrl}
tick[t] &:=& \text{\it logical clock} \in \{0,1\} \\
node[x] &:=& \text{\it input stream} \in\{0,1\} \\
edge[x,y] &:=& \text{\it input stream} \\
weight[x,t] &:=& node[x] \ \times {\rm AggSum}([x], \dfrac{edge[y,x] \times weight[y,t-1]}{{\rm AggSum}([],edge(y,z))}) \times d + \dfrac{1-d}{{\rm AggSum}([],node[z])}
\end{array}\]

{\color{red}
XXX: for non-stratified programs, provide the user facilities like $<+, <-$ to do operations at the next step.

XXX: we need to be able to define aggregation in one of the keys

XXX: have column-oriented / nested tables to avoid keys duplication? how is this compatible with secondary indices ?
}

connect map to its delta to use them

recursion = non-recursive with fixed \# iterations. orthogonal serie of maps

\begin{verbatim}
Goal:
- design language
- incrementalize, generalize this
- trigger/datalog power combined
- different use cases : windowed streams, state machine, continuous queries => get a clean semantics
- locality stuff
- specify location (optionally) => separate from other concerns. @all, @specific, @hashed (to many?)

- ease of use, ease of understanding semantics

=> inflationary semantics, what's cleanest language ?
======> write a roadmap
look at orchestra (datalog + incrementally) [not very interesting]
- clean
simple
locality (orthogonalized)
- distribution
- default locality
- simulate timestamps
- iteration number

Goals:
- explicit deltas, use cases, triggers, active dbs
- what make it easier to do incrementalization easier
\end{verbatim}

for maxflow mincut have sets of flows and union them to construct recursively

instead of hashing tuples to host id, hash to a list of host id => redundancy, then this id can be made "mostly" coherent by doing modulo on group size to get id in group, groups are tagged and a node decides to join to one or more group and join/notifies master at connect

\newpage
The main concern in this problem definition is that the $path$ map is defined recursively, so we need to bind its definition. The proposal is to distinguish two types of maps: extensional and intentional.
Only $edge$ would be extensional here.\ul
\item Extensional (regular) map are modified by triggers
\item Intentional maps are iteratively converted into: 1) a map with 2) associated triggers, 3) additional statements in the existing triggers and possibly 4) materialize streams it depends on into maps.
\ule
The key insight is to see intentional maps as SQL queries over extensional dataset. This means:\ul
\item We can reuse DBToaster machinery to maintain incrementally intentional maps, thereby having <<front-end M3>> where intentional maps declarations are allowed, and <<back-end M3>> where they are converted into additional maps and triggers.
\item The concern of having multiple declaration (for the same map) is solved (as DBToaster will automatically break maintenance into multiple triggers)
\item We do not have to worry about the set and counting semantics of our maps or use deltas.
\item Updates do not need need a specific order because it is implicitly defined by the triggers call chain (that is we will update $path$ before $centrality$ because $centrality$ depends on $path$ in its definition).
\item The logical clock of the system would correspond to the events of external tuples arriving.
\ule

Practically, we could write this program as follows, let the nodes be identified by integers:
\begin{verbatim}
-------------------- SOURCES --------------------
CREATE STREAM sedge(x:int,y:int) FROM ...

--------------------- MAPS ----------------------
DECLARE MAP EDGE[][x:int,y:int] := sedge(x,y);

DECLARE INTENTIONAL MAP PATH[][x:int,y:int,len:int] := EXISTS(EDGE(x,y)) * (len^=1) +
    EXISTS(EDGE(x,z)) * EXISTS(PATH(x,y,l)) * (len^=1+l);

DECLARE INTENTIONAL MAP PATHV[][x:int,y:int,v:int,len:int] := ...
DECLARE INTENTIONAL MAP CENTRALITY[][v:int] := ...

-------------------- QUERIES --------------------
DECLARE QUERY g := CENTRALITY(double)[][v];
------------------- TRIGGERS --------------------
ON + sedge(x,y) { EDGE(x,y) += 1; }
ON - sedge(x,y) { EDGE(x,y) += -1; }
\end{verbatim}
This declaration has no triggers because they will be generated during an M3 intentional$\to$triggers phase. Its result would be the addition of new regular maps and triggers to replace each intentional map.
\newpage
We will expand one by one intentional maps into extensional ones. Intuition: a map is convertible only if its right hand-side contains only extensional maps or itself, and we always append additional statements to existing triggers. Practically, we would obtain:
%  CALL + PATH(x,z,len2) IN PATH(y,z,len) * (len2 ^= len+1)
\begin{verbatim}
--------------------- MAPS ----------------------
DECLARE MAP EDGE[][x:int,y:int] := edge(x,y);
DECLARE MAP PATH[][x:int,y:int,len:int] := ...        -- expand first
DECLARE MAP PATHV[][x:int,y:int,v:int,len:int] := ... -- expand second
DECLARE MAP CENTRALITY[][v:int] := ...                -- expand third
------------------- TRIGGERS --------------------

ON + sedge(x,y) {
  EDGE(x,y) += 1; -- first
  CALL + PATH(x,y,1) -- PATH, base step
}
ON - sedge(x,y) {
  EDGE(x,y) -= 1; -- first
  CALL - PATH(x,y,1) -- PATH, base step
}

ON + PATH(x,y,len) {
  PATH[x,y,len] += 1; -- first
  CALL + PATH(z,y,len2) IN EDGE(z,x) * (len2 ^= len+1) -- PATH inductive step
  ... -- call + PATHV
  ... -- call + CENTRALITY
}

ON - PATH(x,y,len) {
  PATH[] := 0; -- clear all
  CALL + PATH(x,y,len) IN EDGE(x,y) * (len ^= 1) -- rebuild all PATH base steps
  ... -- call - PATHV
  ... -- call - CENTRALITY
}

ON + PATHV(x,y,v,len) {
  ... -- call + CENTRALITY
}
\end{verbatim}
Notes:\ul
\item A trigger always appends to its associated map first and foremost.
\item CALL + ... IN has the same semantics as += but on a trigger instead of a map. If the IN ... part is omitted, it is assumed to be true/1.
\item We need to assume there is no cycles in the graph, otherwise there is no termination. If we have edges (a,b), (b,a) the set of paths is infinite. It should be up to the programmer that make sure that the path does not contain cycles.
\item By expanding the intentional maps, we duplicate the logic of <<base step>> in each of the right hand-side extensional map trigger and the recursive <<inductive step>> in its own trigger. For correctness, we only need to make sure no <<inductive step>> is written outside of the own trigger.
\item Because of incrementality, the idea of <<generations>> mentioned in the implementation details of DataLog is implicit because all previous generations are in the map, whereas next generation is passed through trigger.
\item In the deletion trigger for paths, we need to replay all the construction steps unless we want to tag each tuple with all the base steps it depends on (which might be even more complex).
\ule

\subsubsection*{Discussion}
\ol
\item One concern was the non-termination of programs. If we let the programmer write his own triggers, we can not prevent him from writing:
\begin{verbatim}
ON + EDGE(x,y) { EDGE[x,y] += 1; CALL + EDGE(x,y); }
\end{verbatim}
The set semantics is quite straightforward: we place existential guards to avoid multiple insertions.
\begin{verbatim}
ON + EDGE(x,y) { EDGE[x,y] += 1; CALL + EDGE(x,y) IN EXISTS(EDGE[x,y]) = 0; }
\end{verbatim}
But again, this would not prevent the programmer to shoot himself in the foot by writing recursive non-terminating code. (Unless he is not allowed to edit triggers, but that's maybe not desirable).
\item We might bound the recursion with each trigger call carrying a counter of <<how far from the original stream event>> it is (where far is counter in \# of calls), and avoid recursion above some threshold.
\item We need to have an order between maps, which prevents mutual recursion. One workaround for this is to rewrite the program such that there is only self-recursion in the map definition. An insightful programmer might also write his own trigger to close the loop of mutual recursion.

\item Does order matter? We have two different ways of calling other triggers: we can immediately invoke it or add the next trigger call in a queue. The first method produces DFS-like calls whereas the second strategy behave like BFS. I would argue for the latter one as this would give a coherent behavior to what is achievable with message passing for distributed system.
\item Batching streams? If we only have map add/delete operations in \underline{all} triggers, we may be able to relax the constraints about streams ordering (I think in particular we do not need to wait for a fix-point to be reached before we can send the next external tuple).
\ole

\subsubsection*{Problem 2: metro and busses}
This problem is to test how difficult it is to convert mutual recursion to self-recursion. Say we have a city with locations (as integers) and metro $m(l_1,l_2)$ and busses $b(l_1,l_2)$ connecting these locations. We want to know all locations reachable from $l_0$ and how many changes (to forbid graph union) are required. The maps contain the minimal number of alternated rides. Original statement would be:

\[\begin{array}{rclllll}
RB[l] &:=& {\rm MIN}\big(&b(l_0,l),&RB[l_1] \times b(l_1,l),&RM[l_1] \times b(l_1,l) +1&\big) \\
RM[l] &:=& {\rm MIN}\big(&m(l_0,l),&RM[l_1] \times m(l_1,l),&RB[l_1] \times m(l_1,l) +1&\big) \\
R[l] &:=& {\rm MIN}\big(&RB[l],&RM[l] \big)
\end{array}\]

In this case, we can add an extra field to the tuples to know whether they are in the map RB (ending with a bus) or RM (ending with metro). Hence the transformation look quite general and the problem can be transformed: let $x\in\{B, M, 0\}$ in
\[\begin{array}{rclllll}
R[l,x] &:=& {\rm MIN}\big(&b(l_0,l),&R[l_1,B] \times b(l_1,l),&R[l_1,M] \times b(l_1,l) +1&\big) \times(x\hat=B) \\
&& {\rm MIN}\big(&m(l_0,l),&R[l_1,M] \times m(l_1,l),&R[l_1,B] \times m(l_1,l) +1&\big) \times(x\hat=M) \\
&& {\rm MIN}\big(&R[l,B],&R[l,M] \big)\times(x\hat=0)
\end{array}\]
and our query now become $rides(l):=R[l,0]$ with self-recursion.

Conversion seems quite straightforward but this is due to the fact that $RB$, $RM$ and $R$ have the same domain; this may not be true in general. Can we have mutual recursion for functions that do not operate over the same domain ?

%\begin{verbatim}
%for both problems:
%- write mathemal definition
%- write pseudo M3 code
%- write naive implementation using := to recreate the views at every event
%- write expanded M3 code (using call to incremental view maintenance on intentionally defined maps)
%- give ideas how we could achieve this using existing architecture
%\end{verbatim}

\end{document}


\documentclass{article}

\begin{document}
	\author{Dr. Desmond Moru}
	\title{Cardano's Formula for Cubic Equations}
	\maketitle

	\begin{center}
		\textbf{Abstract}
	\end{center}
   Gerolamo Cardano was born in Pavia 1504 as the illegitimate child of a jurist. He attended the University of Padua and became a physician in the town of Sacco, after being rejected by his home Europe, having treated the Pope. He was also an astrologer and an avid gambler, to which he wrote the Book on Games of chance , which was the first serious treatise on the mathematics of probalitity|l|.

   \section{ Introduction to Cardano's Formula}
  Cardano's formula for solution of cubic equations for an equation like;
  \begin{equation}
  	x^3 + a1x^2 + a2x + a3 = 0
  \end{equation}
the parameters Q, R , S and T can be computed thus,
\begin{equation}
	Q=  \frac{3a_{1}-a_{1}^2}{a}          R=\frac{9a_{1}a_{2}-27a_{3}-2a_{1}^3}{54}
	S=3\sqrt{R\sqrt{-Q^3 + R^2}}
T=\sqrt{R-\sqrt{Q^3 + R^2}}

\end{equation}

to give the roots;

\begin{flushleft}
\begin{equation}
	x_{1} = S + T-\frac{1}{3}a_{1}
	\end{equation}
	\end{flushleft}
\begin{flushleft}
	\begin{equation}
x_{2}=\frac{-S+T}{2} - \frac{a_1}{3} + i\frac{\sqrt{3}(s-T)}{2}
	\end{equation}
\end{flushleft}

	\begin{equation}
		x_{2}=\frac{-S+T}{2} - \frac{a_1}{3} + i\frac{\sqrt{3}(s-T)}{2}
		Note : x^3  must not have a co-efficient
			\end{equation}

	\end{document}