%
% $Id$
%
\label{sec:ecp}
\def\ell{l}
Effective core potentials (ECPs) are a useful means of replacing the core
electrons in a calculation with an effective potential, thereby eliminating
the need for the core basis functions, which usually require a large set of
Gaussians to describe them. In addition to replacing the core, they may be
used to represent relativistic effects, which are largely confined to the
core. In this context, both the scalar (spin-free) relativistic effects and
spin-orbit (spin-dependent) relativistic effects may be included in
effective potentials. NWChem has the facility to use both, and these are
described in the next two sections.

A brief recapitulation of the development of RECPs is given here, following
Pacios and Christiansen\footnote{l.~F.~Pacios and P.~A.~Christiansen,
J.~Chem.~Phys.~{\bf 82}, 2664 (1985)}. The process can be viewed as starting
from an atomic Dirac-Hartree-Fock calculation, done in {\it jj} coupling,
and producing relativistic effective potentials (REPs) for each $\ell$ and
$j$ value, $U^{\rm REP}_{\ell j}$.  From these, a local potential is
extracted, which for example contains the Coulomb potential of the core
electrons balanced by the part of the nuclear attraction which cancels the
core electron charge. The residue is expressed in a semi-local form,
\begin{equation}
U^{\rm REP} = U^{\rm REP}_{LJ}(r) + \sum_{\ell=0}^{L-1}
\sum_{j=|\ell-1/2}^{\ell+1/2} \left[ U^{\rm REP}_{\ell j}(r) -
U^{\rm REP}_{LJ}(r) \right] \sum_m | \ell j m \rangle \langle \ell j m |
\end{equation}
where $L$ is one larger than the maximum angular momentum in the atom.
The scalar potential is obtained by averaging the REPs for each $j$ for a
given $\ell$ to give an averaged relativistic effective potential, or AREP,
\begin{equation}
U^{\rm AREP}_\ell(r) = \frac{1}{2\ell+1} \left[ \ell U^{\rm REP}_{\ell-1/2}(r)
+ (\ell+1) U^{\rm REP}_{\ell+1/2}(r) \right].
\end{equation}
These are summed into the full potential.
%\begin{equation}
%U^{\rm AREP} = U^{\rm AREP}_{L}(r) + \sum_{\ell=0}^{L-1}
%\left[ U^{\rm AREP}_{\ell}(r) -  U^{\rm AREP}_{L}(r)
%\sum_m | \ell m \rangle \langle \ell m |.
%\end{equation}

The spin-orbit potential is obtained from the difference between the REPs
for the two $j$ values for a given \ell, and may be
represented in terms of an effective spin-orbit operator,
\begin{equation}
H^{\rm SO} = {\bf s} \cdot \sum_{\ell=1}^{L-1} \frac{2}{2\ell+1}
\Delta U^{\rm REP}_{\ell} \sum_{mm'}
| \ell m \rangle \langle \ell m | \hat\ell | \ell m' \rangle \langle \ell m' |.
\end{equation}
where
\begin{equation}
\Delta U^{\rm REP}_{\ell} = U^{\rm REP}_{\ell+1/2}(r)
 - U^{\rm REP}_{\ell-1/2}(r).
\end{equation}
The spin-orbit integrals generated by NWChem are the integrals over the sum,
including the factor of $2/(2\ell+1)$, so that they may be treated as an
effective spin-orbit operator without further factors introduced.

The effective potentials, both scalar and spin-orbit, are fitted to
Gaussians with the form
\[
 r^2U_l(r) = \sum_{k} A_{lk} r^{n_{lk}} e^{-B_{lk}r^{2}}
\]
where $A_{lk}$ is the contraction coefficient, $n_{lk}$ is the
exponent of the ``r'' term (r-exponent), and $B_{lk}$ is the Gaussian
exponent.  The $n_{lk}$ is shifted by 2, in accordance with most of the ECP
literature and implementations, i.e., an $n_{lk} = 0$ implies
$r^{-2}$.  The current implementation allows $n_{lk}$ values
of only 0, 1, or 2.

\section{Scalar ECPs}
\label{sec:scalar_ecp}

The optional directive \verb+ECP+ allows the user to describe an effective core
potential (ECP) in terms of contracted Gaussian functions as given above.
Potentials using these functions must be specified explicitly by user input
in the \verb+ECP+ directive.  This directive has essentially the same form
and properties as the standard \verb+BASIS+ directive, except for essential
differences required for ECPs.  Because of this, the ECP is treated
internally as a basis set. The form of the input for the
\verb+ECP+ directive is as follows:

%        [spherical || cartesian default cartesian]
%        [segment || nosegment default segment]

\begin{verbatim}
  ECP [<string name default "ecp basis">] \
        [print || noprint default print]

     <string tag> library [<string tag_in_lib>] \
                  <string standard_set> [file <filename>] \
                  [except <string tag list>]

     <string tag> [nelec] <integer number_of_electrons_replaced>

        ...

     <string tag> <string shell_type>
     <real r-exponent> <real Gaussian-exponent> <real list_of_coefficients>
        ...

  END
\end{verbatim}

ECPs are automatically segmented, even if general contractions are input.
The projection operators defined in an ECP are spherical by default, so
there is no need to include the \verb+CARTESIAN+ or \verb+SPHERICAL+ keyword
as there is for a standard basis set.  ECPs are associated with centers in
geometries through tags or names of centers.  These tags must match in the
same manner as for basis sets the tags in a \verb+GEOMETRY+ and
\verb+ECP+ directives, and are limited to sixteen (16) characters.
Each center with the same tag will have the same ECP.  By default, the
input module prints each ECP that it encounters.  The \verb+NOPRINT+
option can be used to disable printing.  There can be only one active
ECP, even though several may exist in the input deck.  The ECP modules
load ``ecp basis'' inputs along with any ``ao basis'' inputs present.
ECPs may be used in both energy and gradient calculations.

ECPs are named in the same fashion as geometries or regular basis
sets, with the default name being \verb+"ecp basis"+.  It should be
clear from the above discussion on geometries and database entries how
indirection is supported.  All directives that are in common with the
standard Gaussian basis set input have the same function and syntax.

As for regular basis sets, ECPs may be obtained from the standard library.
The names of the sets of ECPs available in the standard
library (their coverage is described in Appendix \ref{sec:knownbasis}) are
\begin{itemize}
\item \verb,"Hay-Wadt MB (n+1) ECP",
\item \verb,"Hay-Wadt VDZ (n+1) ECP",
\item \verb+"LANL2DZ ECP"+
\item \verb+"SBKJC VDZ ECP"+
\item \verb+"Stuttgart RLC ECP"+
\item \verb+"Stuttgart RSC ECP"+
\item \verb+"CRENBL ECP"+
\item \verb+"CRENBS ECP"+
\end{itemize}

The keyword \verb+nelec+ allows the user to specify the number of core
electrons replaced by the ECP.  Additional input lines define the
specific coefficients and exponents.  The variable \verb+<shell_type>+
is used to specify the components of the ECP.  The keyword \verb+ul+
entered for \verb+<shell_type>+ denotes the local part of the ECP.
This is equivalent to the highest angular momentum functions specified
in the literature for most ECPs.  The standard entries (\verb+s, p, d+,
etc.) for \verb+shell_type+ specify the angular momentum projector
onto the local function.  The shell type label of \verb+s+ indicates
the \verb+ul-s+ projector input, \verb+p+ indicates the \verb+ul-p+,
etc.

For example, the Christiansen, Ross and Ermler ARECPs are available in
the standard basis set libary named \verb+{crenbl_ecp}+.  To perform a
calculation on uranyl (UO$_2^{2+}$) with all-electron oxygen
(aug-cc-pvdz basis), and uranium with an ARECP and using the
corresponding basis the following input can be used
\begin{verbatim}
  geometry
    U 0 0  0
    O 0 0  1.65
    O 0 0 -1.65
  end
  basis
    U library crenbl_ecp
    O library aug-cc-pvdz
  end
  ecp
    U library crenbl_ecp
  end
\end{verbatim}

The following is an example of explicit input of an ECP for H$_2$CO.
It defines an ECP for the carbon and oxygen atoms in the molecule.

% \centerline{{\bf H$_2$CO }}

\begin{verbatim}
  ecp
    C nelec 2 # ecp replaces 2 electrons on C
    C ul      # d
            1       80.0000000       -1.60000000
            1       30.0000000       -0.40000000
            2        0.5498205       -0.03990210
   C s        # s - d
            0        0.7374760        0.63810832
            0      135.2354832       11.00916230
            2        8.5605569       20.13797020
    C p       # p - d
            2       10.6863587       -3.24684280
            2       23.4979897        0.78505765
    O nelec 2 # ecp replaces 2 electrons on O
    O ul      # d
            1       80.0000000       -1.60000000
            1       30.0000000       -0.40000000
            2        1.0953760       -0.06623814
    O s       # s - d
            0        0.9212952        0.39552179
            0       28.6481971        2.51654843
            2        9.3033500       17.04478500
    O p       # p - s
            2       52.3427019       27.97790770
            2       30.7220233      -16.49630500
  end
\end{verbatim}

Various ECPs without a local function are available, including those of
the Stuttgart group. For those, no "ul" part needs to be defined. To
define the absence of the local potential, simply specify one contraction
with a zero coefficient:

\begin{verbatim}
     <string tag> ul
     2     1.00000     0.00000
\end{verbatim}

\section{Spin-orbit ECPs}
\label{sec:spinorb_ecp}

The Spin-orbit ECPs can be used with the Density Functional Approach, but
one has to run the calculations without symmetry. Note: when a Hartree-Fock
method is specified the spin-orbit input will be ignored.

Spin-orbit ECPs are fitted in precisely the same functional form as the
scalar RECPs and have the same properties, with the exception that there is
no local potential ul, no $s$ potential and no effective charge has to be
defined. Spin-orbit potentials are
specified in the same way as ECPs except that the directive \verb+SO+ is
used instead of \verb+ECP+. Note that there currently are no spin-orbit
ECPs defined in the standard NWChem library.  The \verb+SO+
directive is as follows:

\begin{verbatim}
  SO [<string name default "so basis">] \
        [print || noprint default print]

     <string tag> library [<string tag_in_lib>] \
                  <string standard_set> [file <filename>]
                  [except <string tag list>]
        ...

     <string tag> <string shell_type>
     <real r-exponent> <real Gaussian-exponent> <real list_of_coefficients>
        ...

  END
\end{verbatim}

Note: in the literature the coefficients of the spin-orbit potentials are NOT
always defined in the same manner. The NWChem code assumes that the spin-orbit
potential defined in the input is of the form:
\begin{equation}
\Delta U^{\rm NWChem}_{\ell} = \frac{2}{2\ell+1} \Delta U_{\ell}
\end{equation}
For example, in the literature the Stuttgart potentials are defined as
$\Delta U_{\ell}$ and, hence, have to be multiplied by $2/(2{\ell}+1)$. On the
other hand, the CRENBL potentials in the published papers are defined as
$\frac{\ell}{2\ell+1} \Delta U_{\ell}$ and, hence, have to be multiplied by
$2/{\ell}$ (Warning: on the CRENBL website the spin-orbit potentials already
have been corrected with the $2/{\ell}$ factor).

%RJH: Align six comment symbols (#) with the other two.--fmr.
%Generally contracted ECP basis sets are not in wide use, but the
%functionality has been included in NWChem for applications where they
%might be useful.


\subsection{EigenFollowing}\index{Jensen@{\bf Jensen, Frank}}\label{t_ef}
\begin{center}
Description of the EF and TS function \\
by\\
Dr Frank Jensen  \\
Department of Chemistry  \\
Odense University  \\
5230 Odense  \\
Denmark
\end{center}

The current version of the EF optimization routine is a combination of the
original EF algorithm of Simons et al.\ (J.\ Phys.\ Chem.\ 89, 52) as
implemented by  Baker (J.\ Comp.\ Chem.\ 7, 385) and the QA algorithm of Culot
et al.\  (Theo.\ Chim.\ Acta 82, 189), with some added features for improving
stability.

\index{Taylor expansion}\index{Hessian}
The geometry optimization is based on a second order Taylor expansion of  the
energy around the current point. At this point the energy, the gradient  and
some estimate of the Hessian are available. There are three fundamental  steps
in determining the next geometry based on this information:
\begin{itemize}
\item  finding the ``best'' step within or on the hypersphere with
    the current trust radius.
\item possibly reject this step based on various criteria.
\item update the trust radius.
\end{itemize}

\begin{enumerate}\index{Eigenvector!following}\index{OMIN}\index{NONR}\index{RSCAL}
\item For a minimum search the correct Hessian has only positive eigenvalues.
For a Transition State (TS) search the correct Hessian should  have exactly one
negative  eigenvalue, and the corresponding eigenvector should be in the
direction  of the desired reaction coordinate.  The geometry step is
parameterized  as $g/(s-H)$, where $s$ is a shift factor which ensure that the
step-length is  within or on the hypersphere. If the Hessian has the correct
structure, a pure  Newton-Raphson step is attempted. This corresponds to
setting the shift factor  to zero. If this step is longer than the trust
radius, a P-RFO step is attempted.  If this is also too long, then the best
step on the hypersphere is made via  the QA formula.  This three step procedure
is the default. The pure NR step can  be skipped by giving the keyword
\comp{NONR}. An alternative to the QA step is to  simply scale the P-RFO step
down to the trust radius by a multiplicative  constant, this can be
accomplished by specifying \comp{RSCAL}.

\index{RMIN}\index{RMAX}\index{CYCLE}\index{MODE}
\item Using the step determined from 1), the new energy and gradient are
evaluated. If it is a TS search, two criteria are used in determining whether
the step is ``appropriate''. The ratio between the actual and predicted energy
change should ideally be 1. If it deviates substantially from this value, the
second order Taylor expansion is no longer accurate. \comp{RMIN} and \comp{RMAX}
(default  values 0 and 4) determine the limits on how far from 1 the ratio can
be before the step is rejected. If the ratio is outside the \comp{RMIN} and
\comp{RMAX} limits, the  step is rejected, the trust   radius reduced by a
factor of two and a new step  is determined. The second criteria is that the
eigenvector along which the  energy is being maximized should not change
substantially between iterations.  The minimum overlap of the TS eigenvector
with that of the previous iteration  should be larger than \comp{OMIN},
otherwise the step is rejected. Such a step  rejection can be recognized in the
output by the presence of (possibly more)  lines with the   same CYCLE number.
The default \comp{OMIN} value is 0.8, which allows  fairly large changes to
occur, and should be suitable for most uncomplicated  systems. See below for a
discussion of how to use \comp{RMIN}, \comp{RMAX} and \comp{OMIN} for
difficult cases. The selection of which eigenvector to follow towards the TS
is  given by \comp{MODE=$n$}, where $n$ is the number of the Hessian
eigenvector to follow.  The default is \comp{MODE=1}. These features can be
turned off by giving suitable  values as keywords, e.g.\ \comp{RMIN=-100
RMAX=100} effectively inhibits step  rejection. Similarly setting \comp{OMIN=0}
disables step rejection based on large  changes in the structure of the TS
mode. The default is to use mode following  even if the TS mode is the lowest
eigenvector. This means that the TS mode may  change to   some higher mode
during the optimization. To turn of mode  following, and thus always follow the
mode with lowest eigenvalue, set \comp{MODE=0}. If  it is a minimum search the
new energy should be lower than the previous.

The  acceptance criteria used is that the actual/predicted ratio should be
larger  than \comp{RMIN}, which for the default   value of \comp{RMIN=0} is
equivalent to a lower  energy. If the ratio is below \comp{RMIN}, the step is
rejected, the trust radius  reduced by a factor of two and a new step is
predicted. The \comp{RMIN}, \comp{RMAX} and \comp{OMIN}  features has been
introduced in the current version of EF to improve the  stability of TS
optimizations. Setting \comp{RMIN} and \comp{RMAX} close to one will give a
very stable, but also very slow, optimization. Wide limits on \comp{RMIN} and
\comp{RMAX} may  in some cases give a  faster convergence, but there is always
the risk that  very poor steps are accepted, causing the optimization to
diverge. The default  values of 0 and 4 rarely rejects steps which would lead
to faster convergence,  but may occasionally accept poor steps. If TS searches
are found to cause problems, the first try should be to lower the limits to 0.5
and 2. Tighter  limits like 0.8 and 1.2, or   even 0.9 and 1.1, will almost
always slow the  optimization down significantly but may be necessary in some
cases.

In minimum  searches it is usually desirable that the energy decreases in each
iteration.  In certain very rigid systems, however, the initial diagonal
Hessian may be so  poor that the   algorithm cannot find an acceptable step
larger than DDMIN, and  the optimization terminates after only a few cycles
with the ``TRUST RADIUS  BELOW DDMIN'' warning long before the stationary point
is reached. In such cases  the user can add \comp{DDMIN=0.0} and  \comp{RMIN}
set to some negative value, say -10, thereby allowing  steps which allow the
energy to increase. An alternative is to use \comp{LET DDMIN=0.0}.

The algorithm has the capability of following  Hessian eigenvectors other than
the one with the lowest eigenvalue toward a TS.  Such higher mode following are
always much more difficult to make converge.  Ideally, as the optimization
progresses, the TS mode should at some point  become the lowest eigenvector.
Care must be taken during the optimization,  however, that the   nature of the
mode does not change all of a sudden, leading to  optimization to a different
TS than the one desired. \comp{OMIN} has been designed for  ensuring that the
nature of the TS mode only changes gradually, specifically  the overlap between
to successive TS modes should be higher than OMIN. While  this concept at first
appears very promising, it is not without problems when  the Hessian is
updated.

As the updated Hessian in each step is only  approximately correct,   there is
a upper limit on how large the TS mode  overlap between steps can be. To
understand this, consider a series of steps  made from the same geometry (e.g.\
at some point in the optimization), but with  steadily smaller step-sizes. The
update adds corrections to the Hessian to  make it a better approximation to
the exact Hessian. As the step-size become  small, the updated Hessian
converges toward the exact Hessian, at least in the  direction of the step.
The old Hessian is constant, thus the overlap between  TS modes thus does not
converge toward 1, but rather to a constant value which  indicate how well the
old approximate Hessian resembles the exact Hessian. Test  calculations suggest
a typical upper limit around 0.9, although cases have been  seen where the
limit is more like 0.7. It appears that an updated Hessian in  general is not
of sufficient accuracy for reliably rejecting steps with TS  overlaps much
greater than 0.80. The default \comp{OMIN} of 0.80 reflects the  typical use of
an updated Hessian. If the Hessian is recalculated in each step,  however, the
TS mode overlap does converge toward 1 as the step-size goes toward  zero, and
in this cases there is no problems following high lying modes.

Unfortunately setting \comp{RECALC=1} is very expensive in terms of computer
time, but  used in conjecture with \comp{OMIN=0.90} (or possibly higher), and
maybe also tighter  limits on \comp{RMIN}   and \comp{RMAX}, it represents an
option of locating transitions  structures that otherwise might not be
possible. If problems are encountered with  many step rejections due to small
TS mode overlaps, try reducing \comp{OMIN}, maybe  all the way down to 0. This
most likely will work if the TS mode is the lowest  Hessian eigenvector, but it
is doubtful that it will produce any useful results  if a high lying   mode is
followed. Finally, following modes other than the  lowest toward a TS indicates
that the starting geometry is not ``close'' to the  desired TS. In most cases it
is thus much better to further refined the  starting geometry, than to try
following high lying modes. There are cases,  however, where it is very
difficult to locate a starting geometry which has  the correct Hessian, and
mode following may be of some use here.
\end{enumerate}


\documentclass[twocolumn,prd,nofootinbib]{revtex4}
%\newcommand\ForRichardOnly[1]{#1}
\newcommand\ForRichardOnly[1]{}
\usepackage{verbatim}
\usepackage{color}     % color text
\usepackage{framed}
\definecolor{shadecolor}{gray}{0.95}
\usepackage{amsmath}
\usepackage{graphicx}  % extend graphics
\usepackage{tabularx}
\usepackage{wrapfig}   % wrap text around figures, if desired
\usepackage{hyperref}

%\newcommand\ForInternalReference[1]{#1}
\newcommand\ForInternalReference[1]{}
\newcommand\editremark[1]{{\color{red} #1}}
\usepackage{mathtools}
\DeclarePairedDelimiter\ceil{\lceil}{\rceil}
\DeclarePairedDelimiter\floor{\lfloor}{\rfloor}

\newcommand\unit[1]{{\rm #1}}
\newcommand\Y[1]{Y^{(#1)}{}}
% GR tools
\newcommand\prederiv[2]{{}^{(#1)}#2}
\newcommand\dualBack{*}
\newcommand\dualForward{\star}
\newcommand\avL{\left< {\cal L}_{(a} {\cal L}_{b)} \right>}
\newcommand\WeylScalar{{\psi_4}}
\newcommand\WeylScalarFourier{{\tilde{\psi}_4}}
\newcommand\mc{{{\cal M}_c}}
% QM TOOLS
\newcommand\qmstate[1]{\left|#1\right \rangle}
\newcommand\qmstateKet[1]{\left\langle#1\right|}
\newcommand\qmstateproduct[2]{\left\langle#1|#2\right\rangle}
\newcommand\qmoperatorelement[3]{\left\langle#1\left|#2\right|#3\right\rangle}
\newcommand\qmoperator[1]{{\bf #1}}

% NUMBERS
\newcommand\nEventsMDC{450}
\newcommand\BS{{\sc Bayestar}}
\newcommand\gstlal{{\sc GSTlal}}
\newcommand\Like{{\cal L}}
\newcommand\LikeRed{{{\cal L}_{\rm red}}}

% CITATIONS
\newcommand\citeMCMC{\cite{LIGO-CBC-S6-PE,2011PhRvD..83h2002D,2011PhRvD..84f2003C,gr-extensions-tests-Europeans2011,gwastro-mergers-PE-Aylott-LIGOATest,2011ApJ...739...99N,2012PhRvD..85j4045V,gw-astro-PE-Raymond,gw-astro-PE-lalinference-v1}}
\newcommand\citeFisher{\cite{1995PhRvD..52..848P,2008PhRvD..77d2001V,2008CQGra..25r4007C,2010PhRvD..82l4065V,gwastro-mergers-HeeSuk-FisherMatrixWithAmplitudeCorrections}}

% JOURNALS
\newcommand\pasp{PASP}
\newcommand\araa{ARAA}
\newcommand\mnras{MNRAS}
\newcommand\physrep{Phys. Rep.}
\newcommand\cqg{CQG}

%
\newcommand\itrprm{\vec{\lambda}}
\newcommand\etrprm{\vec{\theta}}

\begin{document}

\title{Rapid, embarassingly parallel parameter estimation of gravitational waves from compact binary coalescences}
\author{P. Brady}
\email{patrick@gravity.phys.uwm.edu}
\affiliation{Center for Gravitation and Cosmology, University of Wisconsin-Milwaukee, Milwaukee, WI 53201, USA }
\author{E. Ochsner}
\email{evano@gravity.phys.uwm.edu}
\affiliation{Center for Gravitation and Cosmology, University of Wisconsin-Milwaukee, Milwaukee, WI 53201, USA }
\author{R. O'Shaughnessy}
\email{oshaughn@gravity.phys.uwm.edu}
\affiliation{Center for Gravitation and Cosmology, University of Wisconsin-Milwaukee, Milwaukee, WI 53201, USA }
\author{C. Pankow}
\email{pankow@gravity.phys.uwm.edu}
\affiliation{Center for Gravitation and Cosmology, University of Wisconsin-Milwaukee, Milwaukee, WI 53201, USA }

\begin{abstract}
We  introduce an alternative, highly-parallelizable architecture for compact binary parameter estimation.
%
First, by using a mode decomposition  ($h_{lm}$) to represent each physically distinct source and by
prefiltering the data against those modes, we can efficiently evaluate the likelihood for generic source positions and
orientations, independent of waveform length or generation time.
%
Second, by integrating over all observer-dependent (extrinsic) parameters and by using a purely Monte Carlo
integration strategy, we can efficiently \emph{parallelize} our calculation over the intrinsic and extrinsic space.
%
Third, we use existing gravitational-wave searches to identify specific intrinsic (and extrinsic) parameters for further
investigation.
% POINT: Conclusion: Code is fast
As  proof of concept, we have implemented this algorithm using standard time-domain waveforms in a
production environment, processing  each event in less than 1 hour, using roughly $1000$ cores in parallel,
producing posteriors and evidence with reproducibly small statistical errors (i.e., $\lesssim 1\%$ for both).
%
%
As our code has bounded runtime, almost independent of the starting frequency for the signal, a nearly-unchanged strategy could
 estimate NS-NS parameters in the aLIGO era.
% POINT: Mention *operational* for EOBNRv2HM
Our algorithm is both ready-to-use and efficient for any noise curve and existing time-domain model at any mass, including
slow-to-evaluate waveforms like EOBNRv2HM.
\end{abstract}
\maketitle

\begin{widetext}
{\color{red}\textbf{Draft, not for distribution except by permission of the authors}}

{\color{blue}\textbf{For other authors}: Enable internal-use info (development plans; future project ideas; feedback notes) via changing the
  definition of \texttt{\\ForInternalReference}}
\end{widetext}

\ForInternalReference{
\begin{widetext}
\section*{Outline}
The first level of bullets are proposed sections.
The second level of bullets (except in Executive Summary) are proposed subsections.
The third level of bullets are points to make in each subsection.

Section headings added, including reminders re dotting i's/crossing t's.

\begin{itemize}
\item Executive Summary
	\begin{itemize}
	\item Goal: Rapid parameter estimation of CBC GW signals -- target is a few minutes!
	\item Trick \# 1: use mode decomposition and compute $( h_{\ell m} | d )$ once for each mass pair.
		Extremely fast likelihood evaluation as extrinsic parameters are varied.
	\item Trick \# 2: Abandon Markov chain/ nested sampling. They have nice convergence in high dimensions,
		but are serial. Instead, use brute force grid and Monte Carlo technique. Convergence worse in a sense,
		but embarassingly parallel and very rapid evaluations thanks to trick \# 1.
	\item Essentially same cost regardless of waveform evaluation speed. Therefore can use very long signals
		and/or expensive models like EOB.
	\end{itemize}

\item Methods
	\begin{itemize}
        \item Background

	\item Likelihood evaluation
		\begin{itemize}
		\item Start with expression for ${\cal L}$.
		\item Show steps to get in terms of $( h_{\ell m} | d )$.
		\item Note how all extrinsic parameters enter in $Y_{\ell m}$'s and $F_+$, $F_\times$, and thus we can
			evaluate likelihood cheaply for any extrinsic parameters if we fix the intrinsic ones.
		\end{itemize}

	\item Integration over extrinsic parameters
		\begin{itemize}
		\item Do a basic Monte Carlo integral over  extrinsic parameters, at fixed intrinsic parameters
                        Priors (e.g., time window)
%		\item Describe any fancy pants adaption, use of skymaps, etc.
		\end{itemize}
                \begin{itemize}
  	         \item Time marginalization  \textbf{subsection of extrinsic}
		  \begin{itemize}
		  \item Inverse FFT trick gives $(h_{\ell m}(t_c) | d)$ for all values of $t_c$ at once.
		  \item We just sum over a reasonably sized window $\sim 10$ ms.
		  \end{itemize}
                 \item Adaptation (in distance)
                 \item Targeted sampling : skymaps
                \end{itemize}

	\item Covering the intrinsic parameters
		\begin{itemize}
		\item Describe effective Fisher approach to laying out mass points.
		\item Point out quite flexible: can do random or fixed grid, can change ellipse size, distribution inside ellipse,
			could do several ellipses centered on different points. [?]
		\item Point out difficult to go to many intrinsic dimensions. Right now we focus on 2D non-spinning,
			but 3D or 4D is possibly feasible.
			Precession would be very tough.
			Maybe an approximate metric or help from ROM could save the day. [?]
		\end{itemize}

	\item Postprocessing [?]
		\begin{itemize}
		\item Do we need to say anything about collating results, making triplots, P-P plots, etc.?

                  Yes, it's nontrivial for linear spoked.
		\end{itemize}

	\end{itemize}

\item Results: Production environment
	\begin{itemize}
          \item Describe the BNS MDC, from which our examples are drawn
	\item Show posteriors, convince reader they're similar enough to usual Bayesian PE to be trusted.
	\item P-P plots for an ensemble of physical injections (including spin). Show our results are self-consistent.

          Malmquist/selection bias.
	\item Brief (not more than 1-2 paragraphs, 1 simple plot/table) results confirming
		that our method scales favorably with $f_{\rm min}$ and/or EOB.
	\end{itemize}

\item Conclusions -- self-explanatory.

\item Appendices -- Put detailed technical asides here.

  \begin{itemize}
    \item Notation
    \item Data handling: data rate and data selection (time window), psd estimate, inverse spectrum truncation,
      windowing (or not)
  \item Results: Targeted investigations

  -    DAGs on a single event

  - DAGs using the same physics (zero spin) as our model

  \item General and adaptive monte carlo: For-future-reference stuff, including

    - uniform and variance-minimizing weighting to combine integral results with different samplers

  \end{itemize}

\end{itemize}

Citations: Bayesian methods and monte carlo integration \cite{2011RvMP...83..943V}, including numerical recipes and Lepage; comparison
to other PE methods for LIGO
(MCMC,nested sampling) \cite{LIGO-CBC-S6-PE,2011PhRvD..83h2002D,2011PhRvD..84f2003C,gr-extensions-tests-Europeans2011,gwastro-mergers-PE-Aylott-LIGOATest,2011ApJ...739...99N,2012PhRvD..85j4045V,gw-astro-PE-Raymond,gw-astro-PE-lalinference-v1}

\tableofcontents

\end{widetext}
}
\section{Introduction}
\input{introduction.tex}

\section{Executive Summary}
\input{executive_summary.tex}

\section{Binary Waveforms}
\input{waveforms.tex}

\section{Methods}
\input{methods.tex}

\section{Results: Production environment}
\input{results.tex}

\section{Significance and Comparison with related work }
\input{significance_and_comparison.tex}

\section{Conclusions}
\input{conclusions.tex}

\appendix

\section{Notation, definitions, and equations}
\input{notation_etc.tex}

\section{Discrete data handling}
\input{data_handling.tex}

\ForInternalReference{
\input{appendices.tex}
}

\bibliography{overviewexport}
\end{document}


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

This section describes the input blocks associated with the specification of the trial wavefunction in a QMCPACK calculation. These sections are contained within the \texttt{<wavefunction> ...  </wavefunction>} xml blocks. \textbf{Users are expected to rely on converters to generate the input blocks described in this section.} The converters and the workflows are designed such that input blocks require minimum modifications from users. Unless the workflow requires modification of wavefunction blocks (e.g. setting the cutoff in a multi determinant calculation), only expert users should directly alter them.

The trial wavefunction in QMCPACK has a general product form:
\begin{equation}
\Psi_T(\vec{r}) = \prod_k \Theta_k(\vec{r}),
\end{equation}
where each $\Theta_k(\vec{r})$ is a function of the electron coordinates (and possibly ionic coordinates and variational parameters). For problems involving electrons, the overall trial wavefunction must be antisymmetric with respect to electron exchange, so at least one of the functions in the product must be antisymmetric. Notice that, while QMCPACK allows for the construction of arbitrary trial wavefunctions based on the functions implemented in the code (e.g. slater determinants, jastrow functions, etc), the user must make sure that a correct wavefunction is used for the problem at hand. From here on, we assume a standard trial wavefunction for an electronic structure problem,
\begin{equation}
\Psi_T(\vec{r}) =  \textit{A}(\vec{r}) \prod_k \textit{J}_k(\vec{r}),
\end{equation}
where $\textit{A}(\vec{r})$ is one of the antisymmetric functions: 1) slater determinant, 2) multi slater determinant, or 3) pfaffian, and $\textit{J}_k$ is any of the jastrow functions (described in section \ref{sec:jastrow}).  The antisymmetric functions are built from a set of single particle orbitals (\texttt{sposet}). QMCPACK implements 4 different types of \texttt{sposet}, described in the section below. Each \texttt{sposet} is designed for a different type of calculation, so their definition and generation varies accordingly.


\chapter{The Serial Wrapper Object and Driver}
\label{section:serial}
\par
The goal is to solve $AX = Y$ in a serial environment.
Section 1 of the User's Manual presents a listing of the
{\tt AllInOne.c} driver program for solving $AX =Y$.
There are nine steps, and each requires ``mid-level'' knowledge
of several objects of the {\bf SPOOLES} library.
To reduce the complexity of using the library,
(and the complexity rises dramatically in the multithreaded and MPI
environments),
we created the {\tt Bridge} object.
The term ``bridge'' symbolizes spanning the distance between the
{\bf SPOOLES} library and the CSAR-Nastran application code.
The nine steps of the {\tt allInOne.c} driver program is reduced to
three using the {\tt Bridge} object.
\begin{itemize}
\item Initialization and setup step.
\par
Here the {\tt Bridge} object is allocated via a call to {\tt
Bridge\_new()}.
Parameters are set using {\tt Bridge\_set*()} methods.
The setup phase orders the matrix and prepares all the necessary {\bf
SPOOLES} data structures for the factorization and solve that follows.
\item Factorization step.
\par
The matrix is factored via a call to {\tt Bridge\_factor()}.
\item Solution step.
\par
The linear system is solved via a call to {\tt Bridge\_solve()}.
\end{itemize}
\par
The {\tt Bridge} object
has many parameters that control the ordering of the matrix,
the pivoting tolerance (if pivoting is requested),
the drop tolerance (for an approximate factorization),
and so on.
Rather than burden the user with the knowledge of and setting these
parameters, there are decent default values built into the object.
There are also methods to set various parameters to allow the user
some control over the ordering, factor and solve processes.
\par
Section~\ref{section:Bridge:quick-look-serial-driver} takes a quick
look at the {\tt Bridge} driver program (whose complete listing is
found in Appendix~\ref{chapter:serial_driver}).
Section~\ref{section:Bridge:dataStructure} describes the internal
data fields of the {\tt Bridge} object.
Section~\ref{section:Bridge:proto} contains the prototypes and
descriptions of all {\tt Bridge} methods.
\par
\section{A quick look at serial driver program}
\label{section:Bridge:quick-look-serial-driver}
\par
The entire listing of this serial driver is found in
Appendix~\ref{chapter:serial_driver}.
We now extract parts of the code.
\begin{itemize}
\item Decode the input.
\par
\begin{verbatim}
msglvl       = atoi(argv[1]) ;
msgFileName  = argv[6] ;
neqns        = atoi(argv[3]) ;
type         = atoi(argv[4]) ;
symmetryflag = atoi(argv[5]) ;
mtxFileName  = argv[6] ;
rhsFileName  = argv[7] ;
solFileName  = argv[8] ;
seed         = atoi(argv[9]) ;
\end{verbatim}
Here is a description of the input parameters.

\begin{itemize}
\item {\tt msglvl} is the message level.
\item {\tt msgFile} is the message file name
\item {\tt neqns} is the number of equations.
\item {\tt type} is the type of entries:
1 ({\tt SPOOLES\_REAL}) or
2 ({\tt SPOOLES\_COMPLEX}).
\item {\tt symmetryflag} is the type of matrix symmetry:
0 ({\tt SPOOLES\_SYMMETRIC}),
1 ({\tt SPOOLES\_HERMITIAN}) or
2 ({\tt SPOOLES\_NONSYMMETRIC}).
\item {\tt mtxFile} is the name of the file from which to read the {\tt
InpMtx} object for $A$.
The file name must have the form {\tt *.inpmtxb} for a binary file or
{\tt *.inpmtxf} for a formatted file.
\item {\tt rhsFile} is the name of the file from which to read the {\tt
DenseMtx} object for the right hand side $Y$.
The file name must have the form {\tt *.densemtxb} for a binary file or
{\tt *.densemtxf} for a formatted file.
\item {\tt solFile} is the name of the file to write the {\tt
DenseMtx} object for the solution $X$.
The file name must have the form {\tt *.densemtxb} for a binary file or
{\tt *.densemtxf} for a formatted file, {\tt "none"} for no output,
or any other name for a human-readable listing.
\item {\tt seed} is a random number seed used in the ordering process.
\end{itemize}
%
\item Read in the {\tt InpMtx} object for $A$.
\begin{verbatim}
mtxA = InpMtx_new() ;
rc = InpMtx_readFromFile(mtxA, mtxFileName) ;
\end{verbatim}
The {\tt rc} parameter is the error return.
In the driver it is tested for an error, but we omit this from the
present discussion.
%
\item Read in the {\tt DenseMtx} object for $Y$.
\begin{verbatim}
mtxY = DenseMtx_new() ;
rc = DenseMtx_readFromFile(mtxY, mtxFileName) ;
DenseMtx_dimensions(mtxY, &nrow, &nrhs) ;
\end{verbatim}
The {\tt nrhs} parameter contains the number of right hand sides,
or equivalently, the number of columns in $Y$.
%
\item Create and setup the {\tt Bridge} object.
\begin{verbatim}
bridge = Bridge_new() ;
Bridge_setMatrixParams(bridge, neqns, type, symmetryflag) ;
Bridge_setMessageInfo(bridge, msglvl, msgFile) ;
rc = Bridge_setup(bridge, mtxA) ;
\end{verbatim}
The {\tt Bridge} object is allocated by {\tt Bridge\_new()},
and various parameters are set.
The actual ordering of the matrix, symbolic factorization,
and permutation creation are performed inside the {\tt Bridge\_setup()}
method.
%
\item Compute the matrix factorization.
\begin{verbatim}
permuteflag = 1 ;
rc = Bridge_factor(bridge, mtxA, permuteflag, &error) ;
\end{verbatim}
When {\tt permuteflag} is {\tt 1}, it means that the matrix in {\tt
mtxA} has not yet been permuted into the new ordering and so is
done inside the method.
The {\tt error} flag is filled with an error code that tells how far the
factorization was able to proceed.
If {\tt rc = 1}, the factorization completed without any error.
%
\item Solve the linear system.
\begin{verbatim}
mtxX = DenseMtx_new() ;
DenseMtx_init(mtxX, type, 0, 0, neqns, nrhs, 1, neqns) ;
DenseMtx_zero(mtxX) ;
rc = Bridge_solve(bridge, permuteflag, mtxX, mtxY) ;
\end{verbatim}
The {\tt DenseMtx} object {\tt mtxX} is created and initialized to be
the same type and size as {\tt mtxY}.
Its entries are explicitly zeroed (this is not necessary but is a good
idea in general).
The solution is then solved.
Again, note the presence of {\tt permuteflag}.
When {\tt 1}, \texttt{mtxY} needs to be permuted into the new ordering,
and \texttt{mtxX} is returned in the original ordering.
\end{itemize}
\par
\section{The \texttt{Bridge} Data Structure}
\label{section:Bridge:dataStructure}
\par
The {\tt Bridge} structure has the following fields.
\begin{itemize}
%
\item Graph parameters:
\begin{itemize}
\item
{\tt int neqns} : number of equations,
i.e., number of vertices in the graph.
\item
{\tt int nedges} : number of edges
(includes $(u,v)$, $(v,u)$ and $(u,u)$).
\item
{\tt int Neqns} : number of equations in the compressed graph.
\item
{\tt int Nedges} : number of edges in the compressed graph.
\end{itemize}
%
\item Ordering parameters:
\begin{itemize}
\item
{\tt int maxdomainsize} : maximum size of a subgraph to not split any
further during the nested dissection process.
\item
{\tt int maxnzeros} : maximum number of zeros to allow in a front
during the supernode amalgamation process.
\item
{\tt int maxsize} : maximum size of a front when the fronts are split.
\item
{\tt int seed} : random number seed.
\item
{\tt double compressCutoff} : if the \texttt{Neqns} $<$
\texttt{compressCutoff} $*$ \texttt{neqns}, then the compressed
graph is formed, ordered and used to create the symbolic
factorization.
\end{itemize}
%
\item Matrix parameters:
\begin{itemize}
\item
{\tt int type} : type of entries,
{\tt SPOOLES\_REAL} or {\tt SPOOLES\_COMPLEX},
default value is {\tt SPOOLES\_REAL}.
\item
{\tt int symmetryflag} : type of symmetry for the matrix,
{\tt SPOOLES\_SYMMETRIC}, {\tt SPOOLES\_HERMITIAN}
or {\tt SPOOLES\_NONSYMMETRIC},
default value is {\tt SPOOLES\_SYMMETRIC}.
\end{itemize}
%
\item Factorization parameters:
\begin{itemize}
\item
{\tt int sparsityflag} :
{\tt SPOOLES\_DENSE\_FRONTS} for a direct factorization,
or {\tt SPOOLES\_SPARSE\_FRONTS} for an approximate factorization,
default value is {\tt SPOOLES\_DENSE\_FRONTS}.
\item
{\tt int pivotingflag} :
{\tt SPOOLES\_PIVOTING} for pivoting enabled,
or {\tt SPOOLES\_NO\_PIVOTING} for no pivoting,
default value is {\tt SPOOLES\_NO\_PIVOTING}.
\item
{\tt double tau} : used when pivoting is enabled,
all entries in $L$ and $U$ have magnitude less than or equal to
\texttt{tau},
default value is 100.
\item
{\tt double droptol} : used for an approximation,
all entries in $L$ and $U$ that are kept
have magnitude greater than or equal to \texttt{droptol}.
default value is 0.001.
\item
{\tt PatchAndGoInfo *patchinfo} : pointer to an object that
controls special factorizations for optimization matrices
and singular matrices from structural analysis,
default value is \texttt{NULL} which means no special action is taken.
See the Reference Manual for more information.
\end{itemize}
%
\item Pointers to objects:
\begin{itemize}
\item
{\tt ETree *frontETree} : object that defines the factorizations,
e.g., the number of fronts, the tree they form, the number of
internal and external rows for each front, and the map from
vertices to the front where it is contained.
\item
{\tt IVL *symbfacIVL} : object that contains the symbolic
factorization of the matrix.
\item
{\tt SubMtxManager *mtxmanager} : object that manages the
\texttt{SubMtx} objects that store the factor entries and are used
in the solves.
\item
{\tt FrontMtx *frontmtx} : object that stores the $L$, $D$ and $U$
factor matrices.
\item
{\tt IV *oldToNewIV} : object that stores old-to-new permutation vector.
\item
{\tt IV *newToOldIV} : object that stores new-to-old permutation vector.
\end{itemize}
%
\item Message information, statistics and cpu times:
\begin{itemize}
\item
{\tt int msglvl} : message level for output.
When 0, no output, When 1, just statistics and cpu times.
When greater than 1, more and more output.
\item
{\tt FILE *msgFile} : message file for output.
When \texttt{msglvl} $>$ 0, \texttt{msgFile} must not be \texttt{NULL}.
\item
{\tt int stats[6]} : statistics for the factorization.
\begin{center}
\begin{tabular}{ll}
\texttt{stats[0]} : & \# of pivots \\
\texttt{stats[1]} : & \# of pivot tests \\
\texttt{stats[2]} : & \# of delayed rows and columns
\end{tabular}
\begin{tabular}{ll}
\texttt{stats[3]} : & \# of entries in $D$ \\
\texttt{stats[4]} : & \# of entries in $L$ \\
\texttt{stats[5]} : & \# of entries in $U$
\end{tabular}
\end{center}
\item
{\tt double cpus[14]} : cpus for the different functions.
\begin{center}
\begin{tabular}{ll}
\texttt{cpus[0]} : & time to construct \texttt{Graph} \\
\texttt{cpus[1]} : & time to compress \texttt{Graph} \\
\texttt{cpus[2]} : & time to order \texttt{Graph} \\
\texttt{cpus[3]} : & time for symbolic factorization \\
\texttt{cpus[4]} : & total setup time \\
\texttt{cpus[5]} : & time to permute matrix \\
\texttt{cpus[6]} : & time to initialize front matrix
\end{tabular}
\begin{tabular}{ll}
\texttt{cpus[7]} : & time to factor matrix \\
\texttt{cpus[8]} : & time to post-process matrix \\
\texttt{cpus[9]} : & total factor time \\
\texttt{cpus[10]} : & time to permute rhs \\
\texttt{cpus[11]} : & time to solve \\
\texttt{cpus[12]} : & time to permute solution \\
\texttt{cpus[13]} : & total solve time
\end{tabular}
\end{center}
\end{itemize}
\end{itemize}
\par
\section{Prototypes and descriptions of \texttt{Bridge} methods}
\label{section:Bridge:proto}
\par
This section contains brief descriptions including prototypes
of all methods that belong to the {\tt Bridge} object.
\par
\subsection{Basic methods}
\label{subsection:Bridge:proto:basics}
\par
As usual, there are four basic methods to support object creation,
setting default fields, clearing any allocated data, and free'ing
the object.
\par
%=======================================================================
\begin{enumerate}
%-----------------------------------------------------------------------
\item
\begin{verbatim}
Bridge * Bridge_new ( void ) ;
\end{verbatim}
\index{Bridge_new@{\tt Bridge\_new()}}
This method simply allocates storage for the {\tt Bridge} structure
and then sets the default fields by a call to
{\tt Bridge\_setDefaultFields()}.
%-----------------------------------------------------------------------
\item
\begin{verbatim}
int Bridge_setDefaultFields ( Bridge *bridge ) ;
\end{verbatim}
\index{Bridge_setDefaultFields@{\tt Bridge\_setDefaultFields()}}
The structure's fields are set to default values:
\begin{itemize}
\item
\texttt{neqns} = \texttt{nedges} = \texttt{Neqns} =
\texttt{Nedges} = 0.
\item
\texttt{maxdomainsize} = \texttt{maxnzeros}
   = \texttt{maxsize} = \texttt{seed} = -1.
\texttt{compressCutoff} = 0.
\item
\texttt{type} = \texttt{SPOOLES\_REAL}.
\item
\texttt{symmetryflag} = \texttt{SPOOLES\_SYMMETRIC}.
\item
\texttt{sparsityflag} = \texttt{SPOOLES\_DENSE\_FRONTS}.
\item
\texttt{pivotingflag} = \texttt{SPOOLES\_NO\_PIVOTING}.
\item
\texttt{tau} = 100., \texttt{droptol} = 0.001.
\item
\texttt{patchinfo} =
\texttt{frontETree} =
\texttt{symbfacIVL} =
\texttt{mtxmanager} =
\texttt{frontmtx} =
\texttt{oldToNewIV} =
\texttt{newToOldIV} = \texttt{NULL}.
\end{itemize}
The \texttt{stats[6]} and \texttt{cpus[14]} vectors are filled
with zeros.
\par \noindent {\it Return value:}
1 for a normal return, -1 if \texttt{bridge} is \texttt{NULL}.
%-----------------------------------------------------------------------
\item
\begin{verbatim}
int Bridge_clearData ( Bridge *bridge ) ;
\end{verbatim}
\index{Bridge_clearData@{\tt Bridge\_clearData()}}
This method clears the object and free's any owned data.
It then calls {\tt Bridge\_setDefaultFields()}.
\par \noindent {\it Return value:}
1 for a normal return, -1 if \texttt{bridge} is \texttt{NULL}.
%-----------------------------------------------------------------------
\item
\begin{verbatim}
int Bridge_free ( Bridge *bridge ) ;
\end{verbatim}
\index{Bridge_free@{\tt Bridge\_free()}}
This method releases any storage by a call to
{\tt Bridge\_clearData()} and then free the space for {\tt bridge}.
\par \noindent {\it Return value:}
1 for a normal return, -1 if \texttt{bridge} is \texttt{NULL}.
%-----------------------------------------------------------------------
\end{enumerate}
\par
\subsection{Instance methods}
\label{subsection:Bridge:proto:instance}
\par
%=======================================================================
\begin{enumerate}
%-----------------------------------------------------------------------
\item
\begin{verbatim}
int Bridge_oldToNewIV ( Bridge *bridge, IV **pobj ) ;
\end{verbatim}
\index{Bridge_oldToNewIV@{\tt Bridge\_oldToNewIV()}}
This method fills \texttt{*pobj} with its \texttt{oldToNewIV} pointer.
\par \noindent {\it Return value:}
1 for a normal return,
-1 if \texttt{bridge} is \texttt{NULL}.
-2 if \texttt{pobj} is \texttt{NULL}.
%-----------------------------------------------------------------------
\item
\begin{verbatim}
int Bridge_newToOldIV ( Bridge *bridge, IV **pobj ) ;
\end{verbatim}
\index{Bridge_newToOldIV@{\tt Bridge\_newToOldIV()}}
This method fills \texttt{*pobj} with its \texttt{newToOldIV} pointer.
\par \noindent {\it Return value:}
1 for a normal return,
-1 if \texttt{bridge} is \texttt{NULL}.
-2 if \texttt{pobj} is \texttt{NULL}.
%-----------------------------------------------------------------------
\item
\begin{verbatim}
int Bridge_frontETree ( Bridge *bridge, ETree **pobj ) ;
\end{verbatim}
\index{Bridge_frontETree@{\tt Bridge\_frontETree()}}
This method fills \texttt{*pobj} with its \texttt{frontETree} pointer.
\par \noindent {\it Return value:}
1 for a normal return,
-1 if \texttt{bridge} is \texttt{NULL}.
-2 if \texttt{pobj} is \texttt{NULL}.
%-----------------------------------------------------------------------
\item
\begin{verbatim}
int Bridge_symbfacIVL ( Bridge *bridge, IVL **pobj ) ;
\end{verbatim}
\index{Bridge_symbfacIVL@{\tt Bridge\_symbfacIVL()}}
This method fills \texttt{*pobj} with its \texttt{symbfacIVL} pointer.
\par \noindent {\it Return value:}
1 for a normal return,
-1 if \texttt{bridge} is \texttt{NULL}.
-2 if \texttt{pobj} is \texttt{NULL}.
%-----------------------------------------------------------------------
\item
\begin{verbatim}
int Bridge_mtxmanager ( Bridge *bridge, SubMtxManager **pobj ) ;
\end{verbatim}
\index{Bridge_mtxmanager@{\tt Bridge\_mtxmanager()}}
This method fills \texttt{*pobj} with its \texttt{mtxmanager} pointer.
\par \noindent {\it Return value:}
1 for a normal return,
-1 if \texttt{bridge} is \texttt{NULL}.
-2 if \texttt{pobj} is \texttt{NULL}.
%-----------------------------------------------------------------------
\item
\begin{verbatim}
int Bridge_frontmtx ( Bridge *bridge, FrontMtx **pobj ) ;
\end{verbatim}
\index{Bridge_frontmtx@{\tt Bridge\_frontmtx()}}
This method fills \texttt{*pobj} with its \texttt{frontmtx} pointer.
\par \noindent {\it Return value:}
1 for a normal return,
-1 if \texttt{bridge} is \texttt{NULL}.
-2 if \texttt{pobj} is \texttt{NULL}.
%-----------------------------------------------------------------------
\end{enumerate}
\par
\subsection{Parameter methods}
\label{subsection:Bridge:proto:parameters}
\par
%=======================================================================
\begin{enumerate}
%-----------------------------------------------------------------------
\item
\begin{verbatim}
int Bridge_setMatrixParams ( Bridge *bridge, int neqns, int type, int symmetryflag ) ;
\end{verbatim}
\index{Bridge_setMatrixParams@{\tt Bridge\_setMatrixParams()}}
This method sets the number of equations, type of entries,
and symmetry type of the matrix.
\par \noindent {\it Return value:}
\begin{center}
\begin{tabular}{ll}
~1 & normal return \\
-1 & \texttt{bridge} is \texttt{NULL} \\
-2 & \texttt{neqns} $\le$ 0
\end{tabular}
\begin{tabular}{ll}
-3 & \texttt{type} is invalid \\
-4 & \texttt{symmetryflag} is invalid \\
-5 & symmetry flag is Hermitian but type is real
\end{tabular}
\end{center}
%-----------------------------------------------------------------------
\item
\begin{verbatim}
int Bridge_setOrderingParams ( Bridge *bridge, int maxdomainsize, int maxnzeros,
                               int maxsize, int seed, double compressCutoff ) ;
\end{verbatim}
\index{Bridge_setOrderingParams@{\tt Bridge\_setOrderingParams()}}
This method sets parameters needed for the ordering.
\par \noindent {\it Return value:}
\begin{center}
\begin{tabular}{ll}
~1 & normal return \\
-1 & \texttt{bridge} is \texttt{NULL} \\
-2 & \texttt{maxdomainsize} $\le$ 0
\end{tabular}
\begin{tabular}{ll}
-3 & \texttt{maxsize} $\le$ 0 \\
-4 & \texttt{compressCutoff} $>$ 1
\end{tabular}
\end{center}
%-----------------------------------------------------------------------
\item
\begin{verbatim}
int Bridge_setFactorParams ( Bridge *bridge, int sparsityflag, int pivotingflag,
                             double tau, double droptol, PatchAndGoInfo *patchinfo ) ;
\end{verbatim}
\index{Bridge_setFactorParams@{\tt Bridge\_setFactorParams()}}
This method sets parameters needed for the factorization.
\par \noindent {\it Return value:}
\begin{center}
\begin{tabular}{ll}
~1 & normal return \\
-1 & \texttt{bridge} is \texttt{NULL} \\
-2 & \texttt{sparsityflag} is invalid
\end{tabular}
\begin{tabular}{ll}
-3 & \texttt{pivotingflag} is invalid  \\
-4 & \texttt{tau} $<$ 2.0 \\
-5 & \texttt{droptol} $<$ 0.0
\end{tabular}
\end{center}
%-----------------------------------------------------------------------
\item
\begin{verbatim}
int Bridge_setMessagesInfo ( Bridge *bridge, int msglvl, FILE *msgFile ) ;
\end{verbatim}
\index{Bridge_setMessagesInfo@{\tt Bridge\_setMessagesInfo()}}
This method sets the message level and file.
\par \noindent {\it Return value:}
1 for a  normal return,
-1 if \texttt{bridge} is \texttt{NULL},
-2 if \texttt{msglvl} $>$ 0 and \texttt{msgFile} is \texttt{NULL}.
%-----------------------------------------------------------------------
\end{enumerate}
\par
\subsection{Setup methods}
\label{subsection:Bridge:proto:setup}
\par
%=======================================================================
\begin{enumerate}
%-----------------------------------------------------------------------
\item
\begin{verbatim}
int Bridge_setup ( Bridge *bridge, InpMtx *mtxA ) ;
\end{verbatim}
\index{Bridge_setup@{\tt Bridge\_setup()}}
This method orders the graph, generates the front tree, computes
the symbolic factorization, and creates the two permutation vectors.
\par \noindent {\it Return value:}
1 for a  normal return,
-1 if \texttt{bridge} is \texttt{NULL},
-2 if \texttt{mtxA} is \texttt{NULL}.
%-----------------------------------------------------------------------
\item
\begin{verbatim}
int Bridge_factorStats ( Bridge *bridge, int type, int symmetryflag, int *pnfront,
      int *pnfactorind, int *pnfactorent, int *pnsolveops, double *pnfactorops ) ;
\end{verbatim}
\index{Bridge_factorStats@{\tt Bridge\_factorStats()}}
This method takes as input the type and symmetry of the matrix,
and fills the pointer fields with the number of fronts, factor
indices, factor entries, forward and back solve operations,
and factor operations.
\par \noindent {\it Return value:}
\begin{center}
\begin{tabular}{ll}
~1 & normal return \\
-1 & \texttt{bridge} is \texttt{NULL} \\
-2 & \texttt{type} is invalid \\
-3 & \texttt{symmetryflag} is invalid \\
-4 & \texttt{type} is real but \texttt{symmetryflag} is Hermitian \\
-5 & front tree is not present
\end{tabular}
\begin{tabular}{ll}
~-6 & \texttt{pnfront} is \texttt{NULL}  \\
~-7 & \texttt{pnfactorind} is \texttt{NULL}  \\
~-8 & \texttt{pnfactorent} is \texttt{NULL}  \\
~-9 & \texttt{pnsolveops} is \texttt{NULL}  \\
-10 & \texttt{pnfactorops} is \texttt{NULL}
\end{tabular}
\end{center}
%-----------------------------------------------------------------------
\end{enumerate}
\par
\subsection{Factor method}
\label{subsection:Bridge:proto:factor}
\par
%=======================================================================
\begin{enumerate}
%-----------------------------------------------------------------------
\item
\begin{verbatim}
int Bridge_factor ( Bridge *bridge, InpMtx *mtxA, int permuteflag, int *perror ) ;
\end{verbatim}
\index{Bridge_factor@{\tt Bridge\_factor()}}
This method permutes the matrix into the new ordering (if
\texttt{permuteflag} is 1), factors the matrix, and then
post-processes the factors.
\par \noindent {\it Return value:}
\begin{center}
\begin{tabular}{ll}
~1 & normal return, factorization did complete \\
~0 & factorization did not complete \\
\end{tabular}
\begin{tabular}{ll}
-1 & \texttt{bridge} is \texttt{NULL} \\
-2 & \texttt{mtxA} is \texttt{NULL} \\
-3 & \texttt{perror} is \texttt{NULL} \\
\end{tabular}
\end{center}
%-----------------------------------------------------------------------
\end{enumerate}
\par
\subsection{Solve method}
\label{subsection:Bridge:proto:solve}
\par
%=======================================================================
\begin{enumerate}
%-----------------------------------------------------------------------
\item
\begin{verbatim}
int Bridge_solve ( Bridge *bridge, int permuteflag, DenseMtx *mtxX, DenseMtx *mtxY ) ;
\end{verbatim}
\index{Bridge_solve@{\tt Bridge\_solve()}}
If \texttt{permuteflag} is 1, then \texttt{mtxY} is permuted into
the new ordering.
The linear system $AX = Y$ is solved.
If \texttt{permuteflag} is 1, then \texttt{mtxX} is permuted into
the old ordering.
\par \noindent {\it Return value:}
\begin{center}
\begin{tabular}{ll}
~1 & normal return \\
-1 & \texttt{bridge} is \texttt{NULL} \\
-2 & \texttt{X} is \texttt{NULL} \\
-3 & \texttt{Y} is \texttt{NULL} \\
\end{tabular}
\begin{tabular}{ll}
-4 & \texttt{frontmtx} is \texttt{NULL} \\
-5 & \texttt{mtxmanager} is \texttt{NULL} \\
-6 & \texttt{oldToNewIV} needed, but not available \\
-7 & \texttt{newToOldIV} needed, but not available \\
\end{tabular}
\end{center}
%-----------------------------------------------------------------------
\end{enumerate}


\section{Topology and Geometry}

% \subsection{Mesh topology}
While mesh geometry describes the location of mesh vertices in space, mesh topology indicates
how vertices are connected to each other by edges, triangles or any type of mesh element.
Both information are required on a computational mesh to perform mesh visualization,
mechanical modeling, collision detection, haptic rendering, scalar
or vectorial field description.

%Since topological changes are essential for surgery simulators, a common difficulty when designing those simulators is to ensure that the visual, mechanical, haptic and collision behavior of all meshes stay valid and consistent upon any topological change.

% We handle topological changes in a modular and versatile way. Modular since each SOFA component (collision detection, mechanical solver$\ldots$) may be written with little knowledge about the nature of other components; versatile because any type of topological changes can be handled with the proposed design.

Keeping a modular design implies that mesh related information (such as mechanical or visual properties) is not centralized in a single  mesh data structure but is instead spread out in the software components that are using this information.
% \\
% \textbf{\textit{Family of topologies}}\\
We consider meshes that are cellular complexes made of $k$-simplices (triangulations, tetrahedralisation) or $k$-cubes (quad or hexahedron meshes). These meshes are the most commonly used in real-time surgery simulation and can be hierarchically decomposed into $k$-cells, edges being $1$-cells, triangles and quads being $2$-cells, tetrahedron and hexahedron being $3$-cells.
To take advantage of this feature, the  different mesh topologies are structured as a family tree (see Fig.~\ref{fig:BW_Topology_Family_Tree}) where children topologies are made of their parent topology. This hierarchy makes the design of simulation components very versatile since a component working on a given mesh topology type will also work on its derived types. For instance a spring-mass mechanical component only requires the knowledge of a list of edges (an \textit{EdgeSetTopology} as described in Fig.~\ref{fig:BW_Topology_Family_Tree}) to be effective. With this design, a spring-mass  component can be used at no additional cost on triangulation or hexahedral meshes that derive from an \textit{EdgeSetTopology} mesh.

%The proposed hierarchy makes also a distinction between conformal and manifold meshes. While most common FEM components require a mesh to be conformal (but not necessarily manifold), many high-level software components (such as cutting, contact, haptic feedback algorithms) require the mesh to be a manifold where a surface normal is well-defined at each vertex.
\begin{figure}[ht]
    \centering
        \includegraphics[width=0.9\textwidth]{BW_Topology_Family_Tree}
       \caption{Hierarchy of mesh topology. Dashed arrows indicate possible  \textit{Topological Mappings} from a topology object to another.}
    \label{fig:BW_Topology_Family_Tree}
\end{figure}

Topology objects are composed of four functional members:
 \textit{Container},  \textit{Modifier},  \textit{Algorithms} and  \textit{Geometry}.
The  \textit{Container} member creates and updates when needed two complementary arrays. The former describes the $l$-cells included in a single $k$-cell, $l<k$, while the latter gives the $k$-cells adjacent to a single $l$-cell.
From these arrays, generic methods give access to both full topological element description and complete adjacency information.
The  \textit{Modifier} member provides low-level methods that implement
elementary topological changes such as the removal or addition of an element. The  \textit{Algorithms} member provides high-level topological modification methods (cutting, refinement) which
decompose complex tasks into low-level
ones).
The  \textit{Geometry} member provides geometrical information about the mesh (e.g. length, normal, curvature, ...) and requires the knowledge of the vertex positions stored in the  \textit{Degrees of Freedom} component. \\
%Note that these high-level changes may need geometrical information, such as mesh refining, triangular surface cutting or tetrahedra removal in a given region of interest.

\begin{figure}[ht]
    \centering
        \includegraphics[width=0.9\textwidth]{topologyGraph.pdf}
       \caption{Scene Graph of a simple tetrahedral mesh where a topological mapping is defined to have the set of triangles located at the surface of the volumetric mesh.}
    \label{graphExample}
\end{figure}

Another important concept introduced in SOFA is the notion of \textit{Topological Mapping}. Those mappings  define a mesh topology in a from another mesh topology using the same DOFs.  For instance, one may need to apply specific forces on the surface bounding a volume (for instance to model the Glisson capsule surrounding the liver parenchyma). In this context, a \textit{Tetra2TriangleTopologicalMapping} may be used  to generate in a subnode the list of triangles on the border of a tetrahedral surfaces (see Figure \ref{graphExample}). Similarly, one may obtain the set of edges bordering a triangular mesh or the set of quads at the surface of an hexahedral mesh. Topological mapping may be used to split topological cells into other types of cells. Thus, a quad may be split into 2 triangles and an hexahedron into 5 or 6 tetrahedra. Specific mapping components exist to create an tetrahedral mesh from a set of hexahedra or to create triangular meshes from quads.

%An example of graph with Tetrahedral and Triangular Topology objects is given Fig. \ref{graphExample}. It also contains a mapping from the tetrahedral topology to the triangular one.

\begin{figure}[ht]
    \centering
        \includegraphics[width=0.8\textwidth]{BW_Sub_Shell_Diagram}
  %  \caption{Diagram of topological information for the elements of type Vertex, Edge, Triangle and Tetrahedron. \textit{ Sub Elements} (\textit{ bottom-left}) and \textit{ Shell Elements} (\textit{ top-right}) are stored in the \textit{ Container}. At each index $i$: \textit{ AB-Sub} array stores the indices vector of the elements of type \textit{ B} that compose the element of type \textit{ A} indexed by $i$; \textit{ AB-Shell} array stores the indices vector of the elements of type \textit{ A} that are adjacent to the element of type \textit{ B} indexed by $i$.}
    \caption{The two topological arrays stored in a \textit{ Container} correspond to the upper and lower triangular entries of this table. The upper entries provide the $k$-cells adjacent to a $l$-cell, $l<k$. The lower entries describe the $l$-cells included in a $k$-cell. Similar table exists for quad and hexahedron elements.}
    \label{fig:BW_Sub_Shell_Diagram}
\end{figure}

\subsubsection*{Mesh Data Structure}

% Choices of implementation
Containers storing mesh information (material stiffness, list of fixed vertices, nodal masses, ...) are stored in \textit{ components} and are spread out in the simulation tree.
Most containers are simple arrays  with contiguous memory storage and a short direct access time.
This is important for real-time simulation, but bears some drawbacks when elements of these arrays are being removed since it entails the renumbering of elements.
%For instance, when a single element is removed, the last array element is renumbered such that the array stays contiguous.
Fortunately, all renumbering tasks that maintain consistent arrays can be automated and hidden to the user when topological changes in the mesh arise.
Therefore, efficient access of  mesh data structures is granted while the complexity of keeping the container consistent with topological changes is automated.

There are as many containers as topological elements, currently: vertices, edges, triangles, quads, tetras, hexas. These containers are similar to the STL \textit{ std::vector} classes and allow one to store any component-related data structure. A typical implementation of spring-mass models would use an edge container that stores for each edge, the spring stiffness and damping value, the $i^{th}$ element of that container being implicitly associated with the $i^{th}$ edge of the topology. Finally, two other types of containers with similar characteristics have been defined. The former stores a data structure for a subset of topological elements (for instance pressure on surface triangles in a tetrahedralisation) while the latter stores only a subset of element indices.\\

%\subsubsection{Handling Topological Changes}\label{sec:topologicalChanges}

% to reformulate

% So as to make this design compatible with topological changes at each time step of the simulator,
% consistency has to be maintained for all components that rely on topology information, by applying the observer design pattern to the data structure.

% \subsection{Concept of Topological Event}

% \noindent % Order to respect when adding or removing an element (low-level methods)
% Motivation : topological changes are handled in a transparent way for the user through a mechanism of propagation of topological events from the topological components %toward other components.
%Surgery simulation involves complex topological changes on meshes,
%for example when cutting a surface along a line segment, or when locally refining a volume before removing some tissue.
%However, one can always decompose these complex changes into a sequence of elementary operations,
%such as adding an element, removing an element, renumbering a list of elements or modifying a vertex position.
%
%The approach used in \sofa to handle topological changes makes the  update of data structures transparent to the user, through a mechanism of propagation of topological events.
%A topological event corresponds to the intent to add or to
%remove a list of topological elements. But the removal of elements cannot be tackled in the same way as the addition of elements. Indeed, the element removal event must be first notified to
%the other components before the element is actually removed by the \textit{Modifier}.
%Conversely, element addition is first processed by the \textit{Modifier} and then element addition event is notified to other components.
%Besides, the events notifying the creation of elements also include a list of ancestor elements. Therefore, when splitting one triangle into two sub-triangles, each component-related information (\textit{ e.g.} its Young modulus or its mass density) associated with a sub-triangle will be created knowing that the sub-triangle originates from a specific triangle. Such mechanism is important to deal with meshes with non-homogeneous characteristics related to the presence of pathologies.
%
%\vspace{-0.5cm}
%
%\begin{figure}[ht]
%    \centering
%      %  \mbox{
%      %  \includegraphics[width=0.5\textwidth]{Handling_Topological_Changes}
%      %    \includegraphics[width=0.5\textwidth]{Triangle_Splitting}
%      %  }
%        \includegraphics[width=0.8\textwidth]{Handling_Changes}
%    \caption{Handling topological changes, with the example of a \textit{Triangle Set Topology}.
%   \textit{Component} corresponds to any component of the simulation which may need topological information to perform a specific task.
%    Black features indicate the effective change process. Red features show the steps of event notification.}
%    \label{fig:Handling_Changes}
%\end{figure}

% \vspace{-1.5cm}

%\begin{figure}[ht]
%    \centering
      %  \mbox{
      %  \includegraphics[width=0.5\textwidth]{Handling_Topological_Changes}
      %    \includegraphics[width=0.5\textwidth]{Triangle_Splitting}
      %  }
%        \includegraphics[width=0.65\textwidth]{Triangle_Splitting}
%    \caption{Seven steps to split one triangle into two sub-triangles.}
%    \label{fig:Triangle_Splitting}
%\end{figure}

%The mechanism to handle topological changes is illustrated by Fig.~\ref{fig:Handling_Changes}.
%The notification step consists in accumulating the sequence of
%topological events  involved in a high-level topological change into a buffer stored in
%the \textit{ Container}. Then the event list is propagated to all its
%neighbors and leaves beneath by using a visitor mechanism, called a
%\textit{ Topology Visitor}. Once a given component is visited, the topological
%events are actually processed one by one and the data structure used to store mesh related information are automatically updated.
%
%In practice, for each specific component (\textit{ e.g.} spring-mass mechanical component), a set of callback functions are provided describing how to update the data structure (\textit{ e.g.} spring stiffness and damping values) when adding or removing an element (\textit{ e.g.} the edges defined by the two extremities of the springs).
%We applied the observer design pattern so that component-related data structures update themselves automatically.


\subsection{The weak duality theorem}


\chapter{Summary and outlook}\label{ch:summary}

In this thesis, we aim to study the ground-state properties of closed-shell nuclear systems in the IM-SRG(3).
As a first step in that direction, we have implemented a generic IM-SRG(2)/(3) solver,
which we applied at the IM-SRG(2) truncation level to the calculation of the ${}^4\text{He}$ ground-state energy
and at the IM-SRG(2) and IM-SRG(3) level to the pairing Hamiltonian.
At the IM-SRG(2) level, we found excellent agreement between our implementation
and existing IM-SRG(2) implementations and published results~\cite{Stro15imsrgcpp,Herg16imsrglecnotes}.
For the pairing Hamiltonian at the IM-SRG(3) level,
we found that the three-body truncation does reduce the discrepancy between IM-SRG(2) and the exact solution
in the region of large coupling.
This can be interpreted as evidence that the many-body expansion is behaving systematically,
a claim that we would also like to verify in nuclear systems.

In principle, the next step would be to calculate ${}^4\text{He}$
with the same Hamiltonian in the IM-SRG(3),
where one would expect the corrections due to the three-body truncation to be small.
With our $\emax=2$, this amounts to solving a system of approximately 4 billion coupled differential equations,
most of which are the flowing matrix elements of the three-body Hamiltonian $W$.
Of course, many of these matrix elements are not independent,
related to one another via antisymmetry or (anti-)Hermiticity,
and many should be exactly equal to 0,
such as those that are blocked by the Pauli exclusion principle.
By exploiting these symmetries, it may be possible to allow the current implementation
of IM-SRG(3) to also work for ${}^4\text{He}$.
This would offer the ability to look at many different metrics,
such as the flowing ground-state energy and the MBPT corrections,
when implementing a $J$-scheme IM-SRG(3) library.
Even if the performance is insufficient, a calculation can be run for a few integration steps
and the implementation of the fundamental commutators can be used
to benchmark the $J$-scheme implementation of the fundamental commutators.

Looking forward to the next phase of the project,
some key deliverables will be:
\begin{enumerate}
  \item{
    implementing a correct $J$-scheme IM-SRG(3) solver
    for use in nuclear many-body calculations
    using automatic recoupling tools~\cite{Tich20jcoupling};
  }
  \item tuning the performance of the solver to reach single-particle basis sizes large enough
    for observables to be reasonably converged;
  \item calculating the ground-state energies (and possibly other observables) for ${}^4\text{He}$
    and ${}^{16}\text{O}$ in the IM-SRG(3) and systematically studying the effects of the three-body truncation.
\end{enumerate}
It will be interesting to see if the improvement looks significantly different for different Hamiltonians
and if there are some well-reasoned physically-motivated ways to approximate the IM-SRG(3) well
that could be used to extend current large-scale IM-SRG(2) implementations.
Some options for such approximations might be
the inclusion of certain terms that dominate the IM-SRG(3) contributions
or the development of a way to include sparse approximate three-body operators
that provide the dominant IM-SRG(3) contributions.
With a robust implementation of our own,
we will be in an excellent position to systematically study these options and many more.


\chapter{Measurement technology for laser-camera triangulation}
\label{ch:technology}
%
% Original title:
%  La tecnologia di misura per la triangolazione laser-telecamera
%

\textit{In this chapter we will introduce the laser-camera triangulation technology, with particular attention to its details, components and problems. We will also present the camera calibration problem and conclude with a comparison with the main stereo vision technologies.}

% The laser-camera triangulation technology
  \input{./src/chapters/ch2-Technology/0_triangulation.tex}

% Pinhole camera
  \input{./src/chapters/ch2-Technology/1_camera_model.tex}

% Active light sources
  \input{./src/chapters/ch2-Technology/2_laser.tex}

% The camera calibration problem
  \input{./src/chapters/ch2-Technology/3_calibration.tex}
  % \clearpage

% 3D computer vision overview
  \input{./src/chapters/ch2-Technology/4_3d-overview.tex}


\documentclass[12pt,modern]{article}
\usepackage{setspace}
\usepackage{siunitx}
\usepackage{graphicx}
\usepackage[margin=1in]{geometry}

\doublespacing
% \pagestyle{fancy}
% \fancyhf{}
% \lhead{AU Mic Research Overview}
% \rhead{Cail Daley}

\author{Cail Daley}
\title{On the Relation Between Intrinsic and RV-Traced Exoplanet Distributions}

\begin{document}
\maketitle

The true exoplanet distribution across a given parameter (planet mass, semi-major axis, etc.)  is not, of course, perfectly traced by the distribution derived from radial velocity observations.
This is due to a variety of factors and biases, e.g. the bias towards high-mass planets close to their host star.
Assuming we can accurately characterize these biases, it should be possible to find the “true” exoplanet distribution that corresponds to the distribution traced by RV techniques.
While such a goal falls outsides the scope of this project, I would like to take inspiration from this concept and explore the relations between intrinsic distributions and those traced by RV techniques.
This will be a primarily computational project, comprised of at least three major components: (i) creation of exoplanet distributions (ii) creation of an `observed' light curve for each planetary system in a distribution as part of a hypothetical RV survey, and (iii) fitting the lightcurve with MCMC (and possibly nested sampling) techniques.
Each component is discussed in a section below.
As this project is still in its infancy in terms of implementation, I give a short description of my (planned) methodology and then mention some of the problems and questions I've been wrestling with in bullet points. I welcome all commentary, but the bullet points are the things I especially need help on.

\section{Creation of an Exoplanet Distribution}
\label{sec: (1)}
A distribution is made up of a set planetary systems; each system is defined by an inclination and a stellar mass.
I ignore spectral type, stellar metallicity, and distance to the star (these are the ones I can think of; there's probably more).
Spectral type and stellar metallicity seem beyond the scope of this project as there are no simple theoretical relations that I know of between these two qualities and the RV noise/sensitivity.
A variable number of planets are added to each system; each planet is defined by a mass, semi-major axis, eccentricity, argument of periastron $\omega$, and time since periastron $t_0$.

\begin{enumerate}
  \item As discussed in Section \ref{sec: (2)}, the stellar distance clearly limits the minimum semiamplitude $K_1$ that can be detected. What do you think I lose by not taking distance into account, or equivalently, setting all systems to the same (undefined) distance? Are there biases that get `washed out' by doing this?
  \item Should I create a uniform distribution (for example, with the same number of Jupiter-mass planets as Mars-mass planets, or the same number of 50 au planets as 0.5 au planets), or should I try to make the distribution look like our own universe's so that we can directly learn about our own exoplanet distribution?
  The former only allows relative comparisons between the true and observed distributions, and would be pretty simple to set up. The latter would be much trickier and prone to error, but could lead to some more interesting results.. what do you think?
\end{enumerate}

\section{Creating a Lightcurve}
\label{sec: (2)}

I create synthetic radial velocity curves using the system and planet properties described in Section \ref{sec: (1)}; an example can be found in Figure \ref{fig: sample}.
This involves solving Kepler's equation for a set of observation timestamps, etc. etc.
The resulting resulting curves agree well with theoretical predictions; for a $e=0$ Jupiter analogue around a solar analogue, I derive a $K_1$ of \SI{28.42}{m/s}, compared to the theoretical value of \SI{28.43}{m/s}.

\begin{figure}
  \includegraphics[width=\linewidth]{sample_curve}
  \caption{Analytic RV curve of a four-planet system, with planet parameters listed at the top of the figure. The star is a solar analogue.}
  \label{fig: sample}
\end{figure}

One of the key decisions here is how to determine the periods between radial velocity `observations.' The observations can't be scheduled using any a priori knowledge of the system (that's cheating!), but at the same time observations must be taken such that very short-period planets aren't missed. Additionally, I can't have too many data points; not only is this unrealistic, but it will make the MCMC fitting extremely expensive (see Section \ref{sec: (3)}). Seth suggested that I/the survey `take' two data points separated by a day or so; without doing any modeling, I can use difference between the radial velocity values to decide how to space observations. If there's a big jump in the RV value, I might want to come back the next night, but if it barely changes at all I might wait several months. This seems like a good way to do it, but it's rather contrived, so I'd love to here alternatives!

Noise is added to the analytic RV curve to make the data more realistic (Figure \ref{fig: noisy_sample}); at the moment I'm thinking about adding a constant Gaussian noise of width $\sigma$ somewhere between 1 and \SI{5}{km/s}, but this might not be sufficient. Noise (as well as time between observations) is the only thing stopping the MCMC modeling from finding the correct solution every time; as such, it's super important that I make it realistic. Seth suggested adding (quasi)periodic noise to simulate stellar activity cycles, but this may once again be a little too ambitious..

\begin{figure}
  \includegraphics[width=\linewidth]{sample_curve_noisy}
  \caption{Same as Figure \ref{fig: sample}, but with \SI{1}{m/s} Gaussian noise added.}
  \label{fig: noisy_sample}
\end{figure}

\begin{enumerate}
  \item How should I determine the observation time steps?
  \item How should I characterize the noise?
\end{enumerate}

\section{Fitting the Lightcurve}
\label{sec: (3)}

For each system, I will use MCMC methods and maybe nested sampling to fit the `observed' lightcurve.
Because there will be an unknown number of planets in the system, I will probably have to try several different model formalisms, each with a different number of planets.
The $\chi^2$ values of models with different numbers of free parameters are not directly comparable, but I can use the Aikake Information Criterion (AIC) to determine relative goodness of fit.
The AIC basically penalizes you for adding free parameters, since it's almost always possible to get a better fit by using a more complex model.
I think the most (computationally) efficient way to determine the number of planets is to start with a one-planet fit, and then see if a two-planet fit does better, and repeat until a $n$ planet fit does worse than an $n-1$ planet fit. Once this is the case I call it a day for that particular system, and save the best fit model from the most likely model formalism.

\begin{enumerate}
  \item When determining the number of planets that best fits a system with more than $n$ planets, my algorithm would fail if the relative likelihood of an $n$ planet fit is lower than an $n+1$ planet fit. Is this possible? Is there ever a situation where $n$ planets fits worse than $n+1$ planets, assuming there really are at least $n+1$ planets in the system?
\end{enumerate}

\section{Comparing the Distributions}
\label{sec: (4)}
Once all the systems in a distribution have been fit, we can compare the `true' exoplanet distribution to the distribution constructed from the best fit model parameters from each system. While it will be difficult to make statements about our particular exoplanet distribution, it should be possible to make general statements about the regions of exoplanet parameter space that RV observations are sensitive to.

\begin{enumerate}
  \item Once I have the two distributions, what other cool analyses could I do?
\end{enumerate}

\end{document}


\section{Bridges in HECRAS and \anuga{} using an internal boundary operator}
This test compares a prismatic channel flow with a bridge in HECRAS and ANUGA.
A 10m wide, 1000m long channel (slope of 1/200, bankfull depth of 1m,
rectangular cross-section) flows through a floodplain (10m wide on either side
of the channel) (Figure~\ref{schematic}). 500m downstream there is a bridge
with a 1.3m high rectangular opening over the channel, and a deck elevation of
-1m. In HECRAS the bridge is modelled using the energy method, see the
associated HECRAS files for details. In ANUGA the bridge is modelled by
inserting the bridge deck (upper chord) into the topography, with an internal
boundary operator to describe the bridge underflow. The rating curves for the
bridge underflow (used to compute the bridge discharge from the upstream and
downstream stage) were derived for ANUGA from HECRAS by raising the upper chord
of the bridge in HECRAS (far about the flow) and computing internal boundary
tables, which were then copied into a csv file for use by ANUGA. The bridge
overflow in ANUGA is modelled with the shallow water equations (although
riverwalls could also be used to apply weir type equations instead). Both
models have a uniform Manning's n of 0.045, which prevents too much
supercritical flow in HECRAS (and the associated numerical supression of the
inertial terms that HECRAS uses to retain stability).

\begin{figure}
\begin{center}
\includegraphics[width=1.0\textwidth]{hecras_bridge_test/RASGeometry_Bridge.png}
\end{center}
\caption{Screenshot showing the HECRAS model geometry schematization}
\label{schematic}
\end{figure}

A discharge timeseries is imposed upstream for both models, with the discharge
increasing from 1m$^3$/s initially to 70m$^3$/s at the end of the simulation.
Details of the model setup can be seen in the code / input files in this
directory.

\subsection{Results}

Figure~\ref{Reach} show stage timeseries at various stations downstream in each
model. The ANUGA and HECRAS results are qualitatively similar, but differ in
detail.

\begin{figure}
\begin{center}
\includegraphics[width=0.9\textwidth]{CENTRAL_CHANNEL.png}
\end{center}
\caption{Stage at various points downstream in the channel}
\label{Reach}
\end{figure}

In early stages of the simulation when discharges are lower, ANUGA shows stages
slightly below HECRAS (particularly away from the bridge). This reflects the
fact that HECRAS models side-wall friction while ANUGA does not, so there is
more drag in the HECRAS model.

As the discharge increases, the models show more deviation around the bridge
and upstream, and ultimately approach different steady states. At high flows,
the main reason for this is that they use different methods to model the bridge
overflow, which begins when station 525 exceeds -1m. ANUGA uses the shallow
water equations, while HECRAS uses an energy method. Even before this, the
models show differences once the flow goes overbank (above -2.4m at station
525). Because the ANUGA model here has a fairly coarse mesh, numerical
diffusion causes additional drag for overbank flows.

Several additional factors will contribute to deviations between the models.
ANUGA models cross-channel variations in the water surface elevation, which is
assumed constant in HECRAS. The under-bridge flux in ANUGA is based on the
water elevations in the central channel up-and-down stream of the bridge, thus
the 2D representation will have an effect on the under-bridge flow. Further,
since the ANUGA model here is fairly coarsely resolved, the flow details near
the bridge are noticably affected by the choice of flow algorithm. The models
also flux the momentum under the bridge in different ways. ANUGA's method is to
compute the average momentum in each direction along the upstream bridge
inflow, and assume that this is advected by the discharge (as computed from the
internal boundary rating curves). HECRAS's method is based on the energy
equation.


\chapter{Conclusion \& Future Work}\label{chapter:conclusion}
\label{future:fp}
\label{future:intersection}
\label{future:proofautomation}
\label{future:continuations}
\label{future:gradual}
\label{future:errorreporting}
\label{future:ghost}

We presented \toolname, an automatic, sound, and expressive verifier for Haskell code.
%
We started (Chapter~\ref{chapter:tool}) by porting standard refinement types
to Haskell to verify more than 10K lines of popular Haskell libraries.
%
Then~(Chapter~\ref{chapter:refinedhaskell}), we observed that Haskell's
lazy semantics render standard refinement type checking unsound
and restored soundness via a refinement type based termination checker.
%
Next, we presented Abstract~(Chapter~\ref{chapter:abstractrefinements})
and Bounded~(Chapter~\ref{boundedrefinements}) Refinement Types,
that use uninterpreted functions to
\textit{abstract} and \textit{bound} over the refinements of the types.
We used both these techniques to encode higher order, modular specifications
while preserving SMT based decidable and predictable type checking.
%
Finally, we presented Refinement Reflection (Chapter~\ref{refinementrflection})
a technique that reflects terminating, user defined,
Haskell functions into the logic,
turning (Liquid) Haskell into an arbitrarily expressive
theorem prover.
%
We used \toolname to prove correctness of
of sophisticated properties ranging from
safe memory indexing to code equivalence over parallelization~(Chapter~\ref{stringmatcher})

In short, we described how to turn Haskell into a theorem prover
that enjoys both
the SMT-based automatic and predictable type checking
of refinement types
and
the optimized libraries and parallel runtimes of
the mature, general purpose language Haskell.

Though \toolname is already a usable prototype verifier,
as we saw, there are many directions for future work
to further enhance the verification process.

\section{Additional Features}
We start by enumerating a list of desirable features
that, would ease and extend the standard usage of \toolname
as an shallow verified for Haskell code.

\mypara{Intersection Types}
%\label{future:intersection}
% Why we need it
Currently, \toolname assigns each function to have exactly one refinement type.
Allowing a function to have many different types would allow us to specify
that under different preconditions, the function ensures different postconditions.
%
As an example,
when verifying XMonad (\S~\ref{sec:structures})
we would like to ensure that appending lists with unique and disjoint elements,
would give lists with disjoint elements
while being able to reuse the same append list operator to append non unique lists.
%
As a different example, we would like to provide types
with different labels
to primitive operators (\S~\ref{sec:typing})
illustrating that addition preserves termination while
allowing the same addition operator to add potential diverging values.
%

% The problem
While highly usable, it is unclear how to allow intersection types
and preserve the one pass decidable type checking of \toolname.
%
Concretely, the interesting question is how the type system will choose
at each function call the proper type of the function, that is the type
with weaker (pre-) conditions that the supplied arguments
and stronger (post-) conditions than the required result.
% The solution: https://www.cs.cmu.edu/~fp/talks/icfp07-abs.pdf
In the future, we plan to adjust Pfenning's work
on subtyping and intersection typing~\citep{intersectiontypes,pfenning08,}
into the liquid type framework.

\mypara{Label Polymorphism for Strictness Analysis}
Intersection types would allow us to describe that primitive operators
preserve termination, for example addition of two terminating values cannot diverge.
%
We can express this observation we can use label polymorphism
to assign @(+)@ a type that describes that for any termination label @l@~(\S~\ref{sec:typing}),
if both arguments safisfy @l@, then so does the result.
\begin{code}
  (+) :: Int^label -> Int^label -> Int^label
\end{code}
%
We suspect that label polymorphism can be more generally used for
strictness and termination analysis of arbitrary functions.

\mypara{{Fixed-width integer and floating-point numbers}}
%\label{future:fp}
Currently, \toolname encodes
Haskell's fixed-width integers
and floating-point reals as SMT unbounded integers and reals respectively.
This encoding is unsound, as we can easily prove that an increase
function will always increase its argument
\begin{code}
  incr :: n:Int -> {v:Int | n < v}
\end{code}
This specification is unsound, as increasing by one
the maximum bounded integer in Haskell
@incr maxBound@
overflows and returns a negative integer,
\ie an integer less than @maxBound@.
%
To restore soundness we can strengthen @incr@ type to reason about overflows
\begin{code}
  incr :: n:Int -> {v:Int | n < maxBound => n < v}
\end{code}
We suspect that the above type will crucially restrict precision of abstractions.
To prove that @incr n < n@ we need to prove that @n < maxBound@
an information not always available at the call context.
%
In the future we would like to
use SMT bitvector and floating point theories to
establish integer and floating-point
soundness in \toolname without loosing precision of type checking.

\mypara{Proving Termination under Continuations}
% \label{future:continuations}
For soundness under lazy evaluation,
\toolname uses a refinement type based termination checker
to prove that each logical function is terminating.
%
Our termination checker uses a na\"ive heuristic
that the size of the first sized recursive function argument should be decreasing,
where the size is a user specified inductive function mapping a data type to natural numbers.
%
The question that arises is how to specify termination of
continuation data types.
%
As an concrete example consider the @Cnt@ data type
%
\begin{code}
  data Cnt = Emp | Cnt Int (Int -> Cnt)
\end{code}
How do we specify that the following function @go@ terminates?
\begin{code}
  go :: Cnt -> Int
  go Emp = 0
  go (Cnt i f) = go (f i)
\end{code}
Note, that @go@ can indeed diverge if for example it is called with
a diverging continuation @f = \i -> C i f@.
%
Though in practice many terminating functions reduce to termination of @go@,
for example bytestring(\S~\ref{sec:memory-safety}) and parser's manipulation.
%
Yet, currently, we do not know how @go@'s termination preconditions can be encoded.

\mypara{Inference of Abstract and Bounded Refinement Types}
\label{future:ghost}
We saw how Abstract and Bounded Refinement Types can be used to express
modular higher order specification.
%
Currently the user has to manually specify all such abstractions.
From our current examples we observe that these abstractions mostly encode
the weakest preconditions that should be satisfied and could be syntactically
inferred using ideas from the Dijkstra Monad~\ref{dijkstramonad}.
%
Moreover, as discussed in \S~\ref{sec:discussion}
bounded refinement types lead to a relatively complete
specification type system that require no need for ghost variables.
Thus, Bounded Refinement Type inference could be used to automatically eliminate
user specified ghost arguments.

\mypara{Gradual Verification}
% \label{future:gradual}
During verification process, we unsoundly use assumed
proper types for unverified imported functions.
For example, as discussed in~\S~\ref{sec:discussion}
we assumed that the library multiplication is an associative operator.
In future, we plan to use techniques from gradual or hybrid typing
to \textit{automatically} convert such assumptions to ``hybrid" run-time checks
so that run-time violations of these assertions will be transformed to
controlled failures.

\section{Automation on Theorem Prover}
\label{future:theoremproving}

We have used \toolname as a theorem prover
to prove a variety of deep specifications,
ranging from typeclass laws to correctness of parallel computations.
%
Our experience is that that even though we can prove arbitrary complicated
program properties, the treating (Liquid) Haskell as a theorem prover
is a new technique that identifies
important avenues for research.

First, to reason about higher order properties
\toolname is currently using an incomplete technique
that allows the user to manually instantiate the
axioms of $\alpha$- and $\beta$-equivalence.
%
As a future work we would like to develop a
sound, automatic, and complete theory that reasons about
higher order logics.
We conjecture this is feasible,
due to the fact that our refinement terms
are from the simply typed lambda calculus (STLC).
%
Thus, it would be interesting to use the
normalization of STLC to develop a sound
and complete SMT axiomatization, thereby
automating proofs predictably.

Second,
currently, \toolname
is checking each proofs step
in a global environment,
containing all the (proof irrelevant) information
from the previous proof steps.
%
As an optimization, Dafny's calculation environment~\cite{LeinoPolikarpova16}
is checking each proof step creating a separate SMT environment.
%
Such an optimization would highly speed up proof check times in \toolname.

Third and most importantly,
while proofs are \emph{possible},
due to lack of automation, they are
\emph{cumbersome} and \emph{verbose}.
%
For example, to prove program equivalence in the parallelized version
of the string matcher we were required to write 7 times
as much proof code and annotations as the code to be proven equivalent.
%
What is worse is that \emph{most} of our proofs are trivial and only consist of
function unfolding and application of the inductive hypothesis.
There are many ways to automate this proof generation process. Here
we outline four potential directions.
\begin{itemize}
\item A first alternative is to follow Dafny's~\cite{dafny} approach
that assigns a fuel parameter to each recursive function and,
in the logic, uses SMT to automatically unfold each recursive function up to fuel times.
%
The disadvantage of this approach, as is, is that when
a recursive function needs to be unfold more than threshold times,
the users need to themselves provide appropriate SMT instantiations,
Thus the user needs to exactly understand and be able to talk to the solver,
a language different than the target languages (here Haskell).

\item As another alternative, we can use Synquid~\cite{polikarpova16}
to synthesize functions (\ie proof terms) that satisfy their specifications
(\ie theorems).
%
Synquid is using plain Haskell types to synthesize
data driven programs (\eg AVL and Binary Search trees)
whose correctness is checked via SMT based refinement type checking.
%
Since all our proof terms are unit values
we conjecture that proof synthesis via Synquid
will turn out to be brute force theorem instantiation searching,
thus inefficient.
\item
TiP~\cite{tip} and its prodecessor HipSpec~\cite{hipspec}
use SMTs to automatically prove and generate inductive program properties.
%
To use this existing automation, \toolname can invoke TiP
as an external oracle to automatically decide validity of user specified theorems.
%
A weakness of this approach, and in general the usage of an external proof oracle
is that the Haskell user looses control of the proof generation terms:
proofs are now Tip certificates instead of Haskell code,
whose modifications and understanding would require knowledge of the external oracle.

\item
A final and most promising alternative is to create extensible proof scripts (Coq-like tacktics)
using Template Haskell, GHC's compile time metalanguage.
%
Proof generation scripts
that describe proof (\ie by construction) or searching
(\ie an A$*$ algorithm to find the shortest path from the left to the right hand site on an equality)
can be provided and invoked at compile time to automate proof writing,
%
The benefits of this approach are that
1. the proofs will be auto generated Haskell code that can be checked and modified,
2. users can easily create their own proof scripts, and
3. proof scripts will resemble the well studied Coq tactics.
\end{itemize}
%
Though all these techniques can potentially automate the vast majority of
our proofs, choosing which one best fits at the setting of \toolname and
at the taste of the Haskell community is the real future work challenge.

\section{Usability}
We conclude with a vision on how to convert \toolname
a usable program verifier that would be interactively
use to aid rather than hinter code generation.

\mypara{Program Synthesis}
To begin with, since program specifications constitute an abstraction
of the program,
\textbf{program synthesis} techniques can be used to synthesize
code from specifications and vice versa.
%
An interactive interface can suggest, during development,
a safe and verification friendly specification for a given program,
or a valid implementation of a specification.
%

\mypara{Error Reporting \& Diagnosis}
%\label{future:errorreporting}
When verification fails,
\textbf{error reporting and diagnosis} should guide the user
to edit either the code or the specification to repair the program.
%
The challenge in error reporting is how to explain
the source of failure,
without exposing any technical details
of the underlying verification techniques.
%
In LiquidHaskell, TARGET~\cite{TARGET} attempts to explain
type errors via counter examples.
%
On top of counter examples, % I would like to explore whether
Machine Learning techniques could
provide suggestions to new verification users
based on the history of actions verification experts
took to repair their code.
%

\mypara{Runtime optimizations}
Statically proven invariants can be used by compilers
to automatically remove various run time assertions,
leading to rumtime optimizations.
For instance, if verification statically proved that indexing only occurs
within safe bounds, then no runtime in bounds checks are necessary.
%
Or, when verification has statically proven that a @Maybe Int@ value cannot be nothing,
then the compiler should only store the space requires for the @Int@ (and not the @Maybe Int@)
value at runtime.