\chapter{Domains and Coordinate Systems}\label{Chp:ref:coordinates}

If the region of interest is reasonably small a flat Earth can be assumed. In this case
it is sufficient to use a Cartesian domain\index{Cartesian Domain} $\Omega$ in the form
\begin{equation} \label{REF:EQU:INTRO 8}
\Omega = [x^{min}_0, x^{max}_0] \times
 [x^{min}_1, x^{max}_1] \times
 [x^{min}_2, x^{max}_2]
\end{equation}
and use the
where $x_0$ represents the easting, $x_1$ the northing and $x_2$ the altitude in meters, see Figure~\ref{fig:cartesianDomain}.
It is assumed that data are given is longitude-latitude coordinates which are projected using the
Universal Transverse Mercator (UTM) coordinate system\footnote{See
    e.g. \url{http://en.wikipedia.org/wiki/Universal_Transverse_Mercator_coordinate_system}.}.
In this way, all three coordinates can be given in meters with minimal
distortion when visualizing the domain.
The origin in vertical direction (altitude 0) corresponds to sea level.
For some cases, typically if no sufficient data are available, it is appropriate
to add buffer zones in all dimensions. It can be appropriate to add lateral buffer zones if the
extend of the area covered by the available data is small.
Figure~\ref{fig:cartesianDomain} depicts these as areas shaded in red (padding
area) and blue (air buffer).
While the inversion results contain values for the entire domain the buffer zone
should be disregarded when performing any analysis.
In other words, only the region labeled \emph{data area} in
Figure~\ref{fig:cartesianDomain} contains useful information.
Both the thickness of the air layer and the amount of padding in the $x_0$/$x_1$
dimension is configurable when setting up an inversion.

\begin{figure}[ht]
    \centering\includegraphics{cartesian}
    \caption{Illustration of domain extents, mapping and padding area}
    \label{fig:cartesianDomain}
\end{figure}

\begin{figure}[t]
    \centering\includegraphics[width=0.7\textwidth]{geosphir}
    \caption{Geodetic coordinates  $( \lambda, \phi,h)$ of a point $P$ with
cooridnates $(X,Y,Z)=(x_0,x_1,x_2)$ (thanks to the National Geodetic Survey of the National Oceanic and Atmospheric Administration (NOAA),
see \url{http://www.ngs.noaa.gov/)}.
}
    \label{fig:geodeticDomain}
\end{figure}
For larger areas on the Earth surface it is essential consider the curvature of the region of interest. For this case
it is appropriate to describe the domain of interest using longitude, latitude and height above Earth surface to describe
the domain of interest. We use the geodetic coordinates (see Figure~\ref{fig:geodeticDomain}) where the location of a point
is described by its geodetic latitude $\phi$ (in $deg$), longitude
$\lambda$ (in $deg$) and geodetic height $h$ (in $km$)~\cite{Featherstone2008a} where we assume
\begin{equation}
  -90^o \le \phi \le 90^o \mbox{ and } -180^o \le \lambda \le -180^o \;.
\end{equation}
In the following we refer to the $(\phi, \lambda, h)$ as the Geodetic Coordinate system\index{geodetic coordinates}.
In practice we will be interested in a subregion $\Omega$ which is given by the coordinate region
\begin{equation} \label{REF:EQU:INTRO 8b}
\widehat{\Omega} =
 [\lambda^{min}, \lambda^{max}] \times [\phi^{min}, \phi^{max}] \times
 [h^{min}, h^{max}]
\end{equation}
The Cartesian coordinates $(x_0,x_1,x_2)$ of a point are given as
\begin{equation}
\begin{array}{rcll}
   x_0 & = &  (N + f_{h}  \cdot  h) & \cdot \cos(f_{a} \cdot  \phi) \cdot  \cos(f_{a} \cdot  \lambda) \\
   x_1 & = &  (N + f_{h}  \cdot  h) & \cdot  \cos(f_{a} \cdot  \phi) \cdot  \sin(f_{a} \cdot  \lambda) \\
   x_2 & = &  (N \cdot (1-e^2) + f_{h}  \cdot  h ) & \cdot  \sin(f_{a} \cdot  \phi)\\
\end{array}
\label{equ:geodetic:1}
\end{equation}
where $N$ is given as
\begin{equation}
 N = \frac{a}{\sqrt{1- e^2 \cdot \sin^2(f_{a} \cdot  \phi) }}
\label{equ:geodetic:2}
\end{equation}
with the semi major axis length $a$ and $b$ ($ a \ge b$), and the eccentricity
\begin{equation} \label{equ:ref:coordinates:100}
e = \sqrt{2f - f^2} \mbox{ with flattening } f = 1-\frac{b}{a} \ge 0
\end{equation}
The factors $f_{a}$ and $f_{h}$ consider the change of units from
$deg$ to $rad$ and $km$ to $m$, respectively.
Notice that the surface of the ellipsoid (Earth) is described by the case $h=0$.  Table~\ref{REF:FIG:REF:10}
shows values for  flattening semi-major axis for the major reference systems of the Earth.

\begin{table}
\begin{center}
\begin{tabular}{c|lll}
Ellipsoid reference & Semi-major axis a & Semi-minor axis b & Inverse flattening (1/f)\\
\hline
GRS 80 & 6 378 137.0 m & 6 356 752.314 140 m & 298.257 222 101\\
WGS 84 & 6 378 137.0 m & 6 356 752.314 245 m & 298.257 223 563
\end{tabular}
\end{center}
\caption{Geodetic Reference Systems of the Earth}\label{REF:FIG:REF:10}
\end{table}

We need to translate any object from the Cartesian coordinates $(x_i)$ in terms of Geodetic Coordinate system
$(\phi, \lambda, h)$. In the following indexes running through $(\phi, \lambda, h)$ are denoted by little Greek letters $\alpha$,
$\beta$
to separate them from indexes running through the components of the Cartesian coordinates system in little Latin letters.
With this convection the derivative of a function $g$ with respect to the Geodetic coordinates which is given as
\begin{equation}
\begin{array}{rcl}
  g_{,\lambda} & =  & g_{,0} \cdot x_{0,\lambda} + g_{,1} \cdot x_{1,\lambda} + g_{,2} \cdot x_{2,\lambda} \\
  g_{,\phi} & =  & g_{,0} \cdot x_{0,\phi} + g_{,1} \cdot x_{1,\phi} + g_{,2} \cdot x_{2,\phi} \\
  g_{,h} & =  & g_{,0} \cdot x_{0,h} + g_{,1} \cdot x_{1,h} + g_{,2} \cdot x_{2,h} \\
\end{array}
\end{equation}
via chain rule can be written in the compact form
\begin{equation}
  g_{,\alpha}   =    g_{,i} \cdot x_{i,\alpha}
\end{equation}
with
\begin{equation}
 x_{i,\alpha}
=
\left[
\begin{array}{ccc}
-  R_N \cdot \cos(f_{a} \cdot  \phi) \cdot  \sin(f_{a} \cdot  \lambda) & - R_M \cdot \sin(f_{a} \cdot  \phi) \cdot  \cos(f_{a} \cdot  \lambda) &  f_{h}  \cdot  \cos(f_{a} \cdot  \phi) \cdot  \cos(f_{a} \cdot  \lambda)  \\
 R_N  \cdot  \cos(f_{a} \cdot  \phi) \cdot  \cos(f_{a} \cdot  \lambda) &   -  R_M \cdot  \sin(f_{a} \cdot  \phi) \cdot  \sin(f_{a} \cdot  \lambda) &   f_{h}  \cdot  \cos(f_{a} \cdot  \phi) \cdot  \sin(f_{a} \cdot  \lambda) \\
 0 &  R_M  \cdot  \cos(f_{a} \cdot  \phi) &    f_{h}  \cdot  \sin(f_{a} \cdot  \phi) \\
\end{array}
\right]
\end{equation}
with
\begin{equation}
R_M = f_{a}  \cdot (M + f_{h}  \cdot h) \mbox{ and }
R_N = f_{a}  \cdot  (N + f_{h}  \cdot h)
\label{equ:geodetic:5}
\end{equation}
and
\begin{equation}
 M = \frac{a \cdot  (1-e^2) }{(1- e^2 \cdot \sin^2(f_{a} \cdot  \phi))^{\frac{3}{2}}}
\label{equ:geodetic:5b}
\end{equation}
With the coordinate vectors $(u_{\alpha})$ defined as
\begin{equation}
u_{i \alpha} = d_{\alpha \alpha} x_{i,\alpha}
\end{equation}
and scaling factors
\begin{equation}
d_{\lambda \lambda} =  \frac{1}{f_{a} \cdot (N + f_{h} \cdot h) \cdot \cos(f_{a} \cdot  \phi)}  \; ,
d_{\phi \phi} = \frac{1}{f_{a} \cdot (M + f_{h} \cdot h)} \mbox{ and }
d_{h h} = \frac{1}{f_{h}}
\end{equation}
we get
\begin{equation}
g_{,\alpha}   =    g_{,i} u_{i \alpha} \frac{1}{d_{\alpha \alpha}}
\end{equation}
With the fact that
\begin{equation}
 u_{i \alpha} u_{j \alpha} = \delta_{ij} \mbox{ and }  u_{i \alpha} u_{i \beta} = \delta_{\alpha \beta}
\end{equation}
\begin{equation}
g_{,i} = d_{\alpha \alpha} g_{,\alpha}  u_{i \alpha}
\end{equation}
or
\begin{equation}
g_{,i} =
\frac{1}{f_{a} \cdot (N + f_{h} \cdot h) \cdot \cos(f_{a} \cdot  \phi) }  g_{,\lambda}  u_{i \lambda} +
\frac{1}{f_{a} \cdot (M + f_{h} \cdot h)}   g_{,\phi}  u_{i \phi} +
\frac{1}{f_{h}}  u_{i h}
\end{equation}
Moreover for integrals we get by substitution rule
\begin{equation}
dx_0 \; dx_1  \;  dx_2 =\det((x_{i,\alpha}))  \;  d \phi  \;   d\lambda   \;  dh = v \;  d \phi  \;   d\lambda   \;  dh
\end{equation}
with  $v= \frac{1}{d_{\phi \phi} d_{\lambda \lambda} d_{h h}} =
f_{a}^2 f_{h} (M + f_{h} \cdot h) (N + f_{h} \cdot h) \cdot \cos(f_{a} \cdot  \phi)
$.
Notice that for a spherical Earth $e=0$ for which $M=N$ is the radius of the Earth and $M+h$ is the distance from
the center \footnote{It is useful to keep in mind that
for the Cartesian cooridnate system $(x_0, x_1, x_2) = (\phi, \lambda, h)$ and $v=1$ and $d_{\alpha \alpha}=1$}.

\section{Reference Systems}\label{sec:ref:reference systems}
The \class{ReferenceSystem} is an identifier for a coordinate system which is used to define a
transformation from a rectangular domain $\widehat{\Omega}$ to a subregion at and around the surface of the Earth.
Although the terminology can be applied to a any orthogonal coordinate system in practice
we have two relevant cases, namely the case the Cartesian coordinate system where no coordinate transformation
is applied ($\widehat{\Omega}= \widehat{\Omega}$) and a Geodetic coordinate system as described above.
The two class \class{CartesianReferenceSystem} and \class{GeodeticReferenceSystem} as described in the
next subsection implement a \class{ReferenceSystem}.

\subsection{Cartesian Reference Systems}
\begin{classdesc}{CartesianReferenceSystem}{}
the Cartesian reference coordinate system.
\end{classdesc}

\begin{methoddesc}[GeodeticReferenceSystem]{isCartesian}{}
returns \True
\end{methoddesc}

\begin{methoddesc}[CartesianReferenceSystem]{isTheSame}{other}
test if \member{other} is also the Cartesian reference coordinate system
\end{methoddesc}

\begin{methoddesc}[CartesianReferenceSystem]{createTransformation}{domain}
creates the appropriate coordinate transformation \class{CartesianCoordinateTransformation} on a given \member{domain}
from the reference coordinate system.
\end{methoddesc}

\subsection{Geodetic Reference Systems}

\begin{classdesc}{GeodeticReferenceSystem}{
  \optional{ a=6378137.0}
  \optional{, f=1/298.257223563}
  \optional{, name="WGS84"}
}
initializes a geodetic reference system.
\member{a} is the length of the semi-major axis in meter.
\member{f} is the flattening, see equation~\ref{equ:ref:coordinates:100}.
\member{name} sets the name for the reference system
\end{classdesc}

\begin{methoddesc}[GeodeticReferenceSystem]{isCartesian}{}
returns \False
\end{methoddesc}

\begin{methoddesc}[GeodeticReferenceSystem]{getSemiMajorAxis}{}
returns the length of semi major axis
\end{methoddesc}

\begin{methoddesc}[GeodeticReferenceSystem]{getSemiMinorAxis}{}
returns the length of semi minor axis
\end{methoddesc}

\begin{methoddesc}[GeodeticReferenceSystem]{getFlattening}{}
returns the flattening
\end{methoddesc}

\begin{methoddesc}[GeodeticReferenceSystem]{isTheSame}{other}
test if \member{other} defines the same reference coordinate system.
\end{methoddesc}

\begin{methoddesc}[GeodeticReferenceSystem]{createTransformation}{domain}
creates the appropriate coordinate transformation \class{GeodeticReferenceSystem}  on a given \member{domain}
from the reference coordinate system.
\end{methoddesc}

\subsection{Short Cuts}
And some shorts cuts for some standart reference systems:
\begin{funcdesc}{SphericalReferenceSystem}{\optional{R=6378137.0}}
returns the \class{GeodeticReferenceSystem} of a sphere of radius \member{R} in meters.
\end{funcdesc}

\begin{funcdesc}{WGS84ReferenceSystem}{}
returns the \class{GeodeticReferenceSystem} for the WGS84 Ellipsoid, see Table~\ref{REF:FIG:REF:10}.
\end{funcdesc}

\begin{funcdesc}{GRS80ReferenceSystem}{}
returns the \class{GeodeticReferenceSystem} for the GRS80 Ellipsoid, see Table~\ref{REF:FIG:REF:10}.
\end{funcdesc}

\section{Coordinate Transformation}\label{sec:ref:trafo}
A coordinate transformation defines a transformation of a reference domain $\widehat{\Omega}$ using
a coordinate reference system~\footnote{In general any orthogonal coordinate transformation can be supported
by building subclasses of the \class{SpatialCoordinateTransformation}}. The following script shows the usage:
\begin{python}
from escript.ripley import Brick
domain=Brick(10,10, 30, l0=[-35.,-34.], l1=[148.,149], l2=[-40.,40.])
trafo=GeodeticCoordinateTransformation(domain, WGS84ReferenceSystem())
\end{python}
or in a more generic form:
\begin{python}
from escript.ripley import Brick
ref=WGS84ReferenceSystem()
domain=Brick(10,10, 30, l0=[-35.,-34.], l1=[148.,149], l2=[-40.,40])
trafo=ref.createTransformation(domain)
\end{python}
Notice that the coordinate ranges for latitude (\member{l0}) and
longitude (\member{l1}) are given in degree amd
the range for height $h$ above surface (\member{l2}) in $km$.
The \member{trafo} objects provides now access to the volume factor $v$ and the scaling factors $d_{\alpha, \alpha}$.
The class \\ \class{GeodeticCoordinateTransformation} has the following interface:
\begin{classdesc}{GeodeticCoordinateTransformation}{domain \optional{, reference=WGS84ReferenceSystem()}}
defines a geodetic coordinate transformation with \member{domain} ($=\widehat{\Omega}$)
using the reference coordinate system \member{reference}.
Argument \member{domain} needs to be an \escript \class{Domain} object.
\member{reference}, if present, needs to be a \class{GeodeticReferenceSystem} class object.
\end{classdesc}

\begin{methoddesc}[GeodeticCoordinateTransformation]{isTheSame}{other}
tests of \member{other} defines the same coordinate transformation, i.e. uses the same reference system and the same domain.
\end{methoddesc}

\begin{methoddesc}[GeodeticCoordinateTransformation]{isCartesian}{}
returns \False.
\end{methoddesc}

\begin{methoddesc}[GeodeticCoordinateTransformation]{getDomain}{}
returns the domain of the coordinate transformation.
\end{methoddesc}

\begin{methoddesc}[GeodeticCoordinateTransformation]{getReferenceSystem}{}
returns the reference system used to define the coordinate transformation
\end{methoddesc}

\begin{methoddesc}[GeodeticCoordinateTransformation]{getVolumeFactor}{}
returns the volume factor for the coordinate transformation $v$.
\end{methoddesc}

\begin{methoddesc}[GeodeticCoordinateTransformation]{getScalingFactors}{}
returns the scaling factors $d_{\alpha, \alpha}$.
\end{methoddesc}

\begin{methoddesc}[GeodeticCoordinateTransformation]{getGradient}{u}
return the gradient of scalar \member{u} along the axis of
reference coordinate system.
\end{methoddesc}

\subsection{Cartesian Transformation}
In order to be able to use Cartesian coordinates  within \downunder in the same way like geodetic coordinates
one can use the class \class{CartesianCoordinateTransformation}.  It defines the same interface
like the
\class{GeodeticCoordinateTransformation} class:
\begin{python}
from escript.ripley import Brick
ref=CartesianReferenceSystem()
domain=Brick(10,10, 30, l0=[0.,10000], l1=[0.,10000], l2=[-40000.,40000])
trafo=ref.createTransformation(domain)
\end{python}
Notice that the coordinate ranges for North-South extend (\member{l0}) and
East_West extend (\member{l1}) and height above ground level (\member{l2})  are given in meters now.

\begin{classdesc}{CartesianCoordinateTransformation}{domain}
defines a Cartesian coordinate transformation with domain \member{domain}. In fact no coordinate transformation is
transformed.
\end{classdesc}

\begin{methoddesc}[CartesianCoordinateTransformation]{isTheSame}{other}
tests of \member{other} defines the same coordinate transformation, i.e. uses the same reference system and the same domain.
\end{methoddesc}

\begin{methoddesc}[CartesianCoordinateTransformation]{isCartesian}{}
returns \True.
\end{methoddesc}

\begin{methoddesc}[CartesianCoordinateTransformation]{getDomain}{}
returns the domain of the coordinate transformation.
\end{methoddesc}

\begin{methoddesc}[CartesianCoordinateTransformation]{getReferenceSystem}{}
returns the reference system used to define the coordinate transformation (an instance of \class{CartesianReferenceSystem})
\end{methoddesc}

\begin{methoddesc}[CartesianCoordinateTransformation]{getVolumeFactor}{}
returns the volume factor for the coordinate transformation $v$ ($=1$).
\end{methoddesc}

\begin{methoddesc}[CartesianCoordinateTransformation]{getScalingFactors}{}
returns the scaling factors $d_{\alpha \alpha}$ ($=1$).
\end{methoddesc}

\begin{methoddesc}[CartesianCoordinateTransformation]{getGradient}{u}
return the gradient of scalar \member{u} along the axis of
reference coordinate system.
\end{methoddesc}


\section{Fitting Data}

\begin{slide}{Fitting Strategies}

  \begin{cenpage}{135mm}
  Data analysis seeks a {\RedEmph{Model}} that best matches a
  {\BlueEmph{Measurement}}.

  \vmm

  We'll use $\chi^2$ (don't confuse with EXAFS $\chi$!!) to describe how
  good the match is:

  \[ \chi^2  =
  \sum_i^{N_{\rm fit}} \frac{[\chi_i^{\rm measured} - \chi_i^{\rm
      model}({x})]^2}{\epsilon^2}
  \]

  where
  \begin{itemize}
  \item $N_{\rm fit} = $ number of points in the data to fit.
  \item $\epsilon = $ the  estimated noise  level in the data.
  \item $x$  is the set of parameters to be varied in the analysis
  \end{itemize}

  \begin{center}
    {\RedEmph{ The Best Fit is the one with lowest $\chi^2$. }}
  \end{center}

  \vmm   \hrule \vmm

  \onslide+<2->

  Questions:

  \begin{enumerate}
  \item How do I know how many independent measurements I have?
  \item What is $\epsilon$ for my data?
  \item What parameters can/should I vary?
  \end{enumerate}
\end{cenpage}
\end{slide}

\begin{slide}{The Information Content of EXAFS}

\begin{cenpage}{135mm}
    The number of parameters we can reliably extract from our data is limited:
    \vspace{1mm}

    \begin{postitbox}{26mm}
      $\displaystyle  N_{\rm idp} \approx { \frac{2 \Delta k \Delta R}{\pi}}  $
    \end{postitbox}

    \vmm

    where $\Red{ \Delta k}$ and $\Red{ \Delta R}$ are the $k$- and
    $R$-ranges of the usable data.

    \onslide+<2->
    \vmm\vmm

    For a typical range of $k = [3.0, 12.5] \rm\,\AA^{-1}$ and $R = [1.0,
    3.0] \rm\,\AA$, there are $\sim 12$ parameters that can be determined
    from EXAFS.      \onslide+<2-> That's not much!

    \onslide+<2->
    \vmm\vmm

    The Fit statistics and confidence in the measured parameters need to
    reflect this.  But we usually oversample our data ($N_{\rm fit} >
    N_{\rm idp} $) so we have

    \begin{postitbox}{56mm}
      $ \displaystyle
      \chi^2  =  \frac{ N_{\rm idp}}{\epsilon^2 N_{\rm fit}}
      \sum_i^{N_{\rm fit}} [\chi_i^{\rm measured} - \chi_i^{\rm model}({x})]^2
      $
    \end{postitbox}

    Note: I also assumed $\epsilon$ is a constant.

\vfill
\end{cenpage}
\end{slide}

\begin{slide}{Other Fitting Statistics}

  \begin{cenpage}{135mm}
  Other ``goodness-of-fit statistics'':

\vmm\vmm

  \begin{columns}[T]
    \begin{column}{65mm}
      {\RedEmph{chi-square}}: As before:

    \begin{postitbox}{56mm}
      \[
      \chi^2  =  \frac{ N_{\rm idp}}{\epsilon^2 N_{\rm fit}}
      \sum_i^{N_{\rm fit}} [\chi_i^{\rm measured} - \chi_i^{\rm model}({x})]^2
      \]
    \end{postitbox}
    \end{column}
    \begin{column}{65mm}
      {\RedEmph{reduced chi-square}}: scale by the ``degrees of freedom'' :

      \begin{postitbox}{56mm}
        \[ \chi^2_\nu =  \chi^2 / (N_{\rm idp}-N_{\rm varys})      \]
        \end{postitbox}
    \end{column}
  \end{columns}

  \vmm  \vmm  \pause

  \begin{columns}[T]
    \begin{column}{65mm}

      {\RedEmph{R-factor}}: $\cal{R}$  gives a ``fractional misfit'' (and
      not scaled by the data  uncertainty $\epsilon$):

      \begin{postitbox}{56mm}
        \[
      {\cal{R}} = \frac{\sum_i^{N_{\rm fit}}[\chi_i^{\rm measured} -
        \chi_i^{\rm model}({x})]^2 }{
        \sum_i^{N_{\rm fit}} [{\chi_i^{\rm measured}}]^2}
    \]
  \end{postitbox}

    \end{column}
    \begin{column}{65mm}

      {\RedEmph{Akaike Information Criterion}}: Also weights to account for
      degrees of freedom in fit:

      \begin{postitbox}{56mm}
        \[
          {\rm{AIC}} =N_{\rm data}  \log(\chi^2/N_{\rm data}) + 2 N_{\rm varys}
        \]
      \end{postitbox}

    \end{column}
  \end{columns}

  \vmm
  For a ``Good Fit'', $\chi^2_\nu$ should be $\sim$ 1.

  This assumes that  we have an accurate estimate of $\epsilon$ which never really happens!

\vmm

\vfill
\end{cenpage}
\end{slide}

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

\section{Uncertainties in $\chi(k)$}
\begin{frame}\frametitle{Propagation of uncertainties in $\chi(k)$}

\begin{cenpage}{135mm}

  Estimating uncertainties in  $\chi(k)$ has always been a challenge.

  \vmm

  We have (by default) estimated the uncertainty in $\chi(k)$ as
  {\BlueEmph{white noise}} {\tiny{(Newville, Boyanov, and Sayers, {\emph{J
          Synch Rad}}, 1999)}}, using $\chi(R)$ between [15, 25] \AA.

\begin{columns}
  \begin{column}[T]{60mm}

    {\onslide+<1->  \includegraphics[width=60mm]{figs/errors/feo_chir}  }

  \end{column}
  \begin{column}[T]{60mm}

    {\onslide+<2-> \includegraphics[width=60mm]{figs/errors/feo_chir_logscale} }

  \end{column}
\end{columns}

{\onslide+<2->

  \begin{cenpage}{105mm}

    The ``high-R'' portion of $\chi(R)$ can estimate the
    ``white noise'' in the data pretty well.

    \vmm
    This is easy to do, but we know it misses an important component:
  \end{cenpage}

  \begin{postitbox}{63mm}
      {uncertainties from  background subtraction}
  \end{postitbox}

}
\end{cenpage}

\end{frame}

\begin{frame}\frametitle{ Uncertainties in $\chi(k)$ from background subtraction}

  \begin{cenpage}{135mm}

\vmm
\begin{cenpage}{105mm}

  We can propagate the uncertainties from the fit of the background spline
  to estimate the uncertainty in $\chi(k)$ from the background subtraction.

  \vmm \vmm

  This is {\BlueEmph{not white noise}}.   In fact, it tends to have a peak
  somewhat above $2 R_{\rm bkg}$
\end{cenpage}

\begin{columns}
  \begin{column}[T]{60mm}

    {\only<1> { \includegraphics[width=60mm]{figs/errors/feo_chik_deltachi}}}

    {\only<2,3> { \includegraphics[width=60mm]{figs/errors/feo_deltachik_rbkg} }}

    \end{column}

    \begin{column}[T]{60mm}

      {\only<1>{ \includegraphics[width=60mm]{figs/errors/feo_chir_deltachi} }}

      {\only<2,3>{ \includegraphics[width=60mm]{figs/errors/feo_deltachir_rbkg} }}

    \end{column}

\end{columns}

\vmm

{\onslide+<3-> {

\begin{cenpage}{105mm}

  Using this $\delta\chi(k)$ array as the estimate of the uncertainty of
  the EXAFS $\chi(k)$ reduces the $\chi^2$ statistic by $2\times$ or more.
  \vmm

    This is now the default approach in {\larch}.

\end{cenpage}

}}

\end{cenpage}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%
\begin{slide}{Error Bars: the uncertainties in the fit variables}

\begin{cenpage}{135mm}
A fit finds the ``best-fit'' set of values for the variables $\{\Blue{x},
{\Blue{y}}, \ldots\}$:  these  give the lowest  $\chi^2$ = $\chi^2_0$.

\begin{center} Uncertainties in Parameters $\Blue{x}$ are estimated by increasing the
  $\chi^2$ by 1:
\end{center}

\begin{columns}
\begin{column}{65mm}

\onslide+<2->

 \includegraphics[width=62mm]{figs/errors/ellipse}

\end{column}
\begin{column}{60mm}

{\onslide+<2->
Some Parameters are {\RedEmph{Correlated}}:

\vmm

Changing the value for parameter {\Blue{$x$}} away from its best value will change the best value
for another parameter, {\Blue{$y$}}.

\vmm

\begin{postitbox}{53mm}
  For EXAFS, ($R$, $E_0$) and ($N$, $\sigma^2$) are usually very highly
  correlated ($>0.85$).
\end{postitbox}
\vmm
}
\end{column}
\end{columns}

 \onslide+<2-> \vmm
 {\RedEmph{Increasing $\chi^2$ by 1 assumes we have a ``Good Fit'', with $\chi^2_\nu \approx 1$}}.

 \vmm We typically have  $\chi^2_\nu \sim 10$,  so we increase the best $\chi^2$ by $\chi^2_\nu$ to estimate error bars.

\vmm
The reported uncertainties do take the correlation into account!

\vmm
More rigorous methods for uncertainty analysis is available from the {\larch}
Python code.

\vmm \vmm
\end{cenpage}

\end{slide}

% %%%%%%%%%%%%%%%%%%%%%%
% \begin{slide}{Error Bars: correlations between fit variables}

%     Pairs of variables can be {\RedEmph{correlated}}: changing one variable away
%     from its optimum value can be compensated by changing another variable away
%     from its best value.  The uncertainties needs to take correlations into
%     account.

%     \vmm\pause

%     \begin{center} \wpdf{50mm}{figs/errors/ellipse2}   \end{center}

%     \vmm
%     The uncertainty in $x$ is $\delta x$, NOT  $\delta x'$!

%     \vmm

%     The correlation between variables is given by the slope of the ellipse:

%     \begin{postitbox}{75mm}    how much does $y$ want to change when
%       changing $x$?
%     \end{postitbox}

%     \vmm

% \vfill
% \end{slide}


\documentclass[twoside]{MATH77}
\usepackage[\graphtype]{mfpic}
\usepackage{multicol}
\usepackage[fleqn,reqno,centertags]{amsmath}
\begin{document}
\opengraphsfile{pl02-02}
\begmath 2.2 Error Function, Gaussian Probability Integral, etc.

\silentfootnote{$^\copyright$1997 Calif. Inst. of Technology, \thisyear \ Math \`a la Carte, Inc.}

\subsection{Purpose}

These subprograms compute values of the error function,
the complementary
error function, and an exponentially scaled complementary error
function, \cite{ams55:erf,Hart:1968:CA:erf}.  The closely related Gaussian or
normal probability integral can be computed by subprograms described in Chapter
15.2.

Error function:
\begin{align*}
\erf (x)&=\frac 2{\sqrt{\pi }}\int_0^xe^{-t^2}dt\\
\intertext{Complementary error function:}
\erfc (x)&=1-\erf (x)=\frac 2{\sqrt{\pi }}\int_x^\infty e^{-t^2}dt\\
\intertext{Exponentially scaled complementary error function:}
\erfce (x)&=\exp (x^2)\ \erfc (x)
\end{align*}
\subsection{Usage}

\subsubsection{Program Prototype, Single Precision}

\begin{description}
\item[REAL]  \ {\bf X, Y, SERF, SERFC, SERFCE}
\end{description}

Assign a value to X and obtain the value of erf, erfc, or erfce,
respectively, as follows:
$$
\fbox{{\bf Y = SERF(X)}} \hspace{.4in} \fbox{{\bf Y = SERFC(X)}}
$$
$$
\fbox{{\bf Y = SERFCE(X)}}
$$

\subsubsection{Argument Definitions}

\begin{description}
\item[X]  \ [in] Argument at which function evaluation is desired. Require
$\text{X} \geq 0$ when using SERFCE.

\item[Y]  \ [out] Value of function returned.
\end{description}

\subsubsection{Modifications for Double Precision}

For double precision change the REAL type statement to DOUBLE PRECISION and
change the function names to DERF, DERFC, and DERFCE.

\subsection{Examples and Remarks}

See DRSERF and ODSERF for an example of the usage of these subprograms.

The ANSI Fortran 77 standard does not include the error function, or the
related functions, erfc and erfce, as intrinsic functions.

Some Fortran systems, however, do provide such functions. For example,
UNISYS ASCII Fortran and IBM VS-Fortran provide ERF, ERFC, DERF, and DERFC,
with ERF and ERFC being ``generic," whereas VAX-11 Fortran does not provide
these functions.

In a system having DERF or DERFC as intrinsics, a reference to one of these
function names will cause the vendor-supplied code to be used. If one wishes
to override this and use the code from this library one must declare the
function name to be EXTERNAL in the referencing program unit.

Whenever the user's mathematical problem involves the expression, $1-\erf (x)$%
, $\erfc (x)$ should be used instead. This will give significantly better
relative accuracy as $x$ increases above 0.5, and no worse accuracy for $x <
0.5.$

In cases in which the user's problem involves the expression, $\exp (x^2)
[1-\erf (x)]$, with $x \geq 0$, $\erfce (x)$ should be used. This avoids the
problem of $\exp (x^2)$ reaching the overflow limit for fairly modest values
of $x$, since $\erfce (x)$ is asymptotic to $1/(x\ \pi ^{1/2})$ as $x$
approaches infinity.

\subsection{Functional Description}

The function $\erf (x)$ is an odd function, increasing monotonically from $-$1
at $x = -\infty $ to +1 at $x = +\infty .$
The function $\erfc (x) = 1 - \erf (x)$ approaches zero rapidly as $x$
increases. More specifically, $\erfc (x)$ is asymptotic to
\begin{equation*}
u(x) =  \exp (-x^2) / (x \sqrt \pi) \text{ as }x \rightarrow + \infty .
\end{equation*}
For $x > 5$, $\erfc (x)$ satisfies $0.98 u(x) < \erfc (x) < u(x)$.
\vspace{10pt}

\hspace{5pt}\mbox{\input pl02-02 }

The largest value of $x$ for which $\erfc (x)$ does not underflow is estimated
by this subprogram using the System Parameters subprogram on first entry.
Examples of this limiting value, called XMAX in the subprogram, are 9.18 for
IEEE single precision and 26.53 for IEEE double precision.

The mathematical function $\erfce (x)$ is defined for all $x$ but it is
expected to be used only for large positive $x$. Thus the subprograms SERFCE
and DERFCE are designed only for use with $x \geq 0.$

These subprograms are based on polynomial approximations and code due to L.
W. Fullerton, Los Alamos, 1977, and rational approximations due to W. J.
Cody, \cite{Cody:1969:RCA}. By use of the System Parameters subprogram the
accuracy adjusts to the machine precision. The stored coefficients provide for
precision to about 30 significant decimal digits for DERF, DERFC, SERF, and
SERFC. The accuracy for DERFCE and SERFCE is up to 30 significant decimal
digits for $0 \leq x \leq $ XMAX, and up to 18 digits for $x \geq $ XMAX.

\subparagraph{Accuracy Tests}

The single precision subprograms were tested on a UNISYS 1100 by comparison
with the corresponding double precision subprograms at over 45000 points.
The relative precision of the UNISYS single precision arithmetic is $\rho =
2^{-27} = 0.745$\,E$-8$. The test results may be summarized as follows:

\begin{center}
\begin{tabular}{lcr}
 & {\bf Argument} & \multicolumn{1}{c}{\bf Max. Rel.}\\
\multicolumn{1}{c}{\bf Function} & {\bf Interval} &
\multicolumn{1}{c}{\bf Error}\\
SERF & \multicolumn{1}{c}{$x \leq 1$} & $2.1\rho $\rule{.25in}{0pt}~\\
 & $x \geq 1$ & $1.2\rho $\hspace{.25in}\rule[-7pt]{0pt}{8pt}\\
SERFC & [$-$7, 0.5] & $2.1\rho $\rule{.25in}{0pt}\\
 & [0.5, 1.0] & $5.1\rho $\rule{.25in}{0pt}\\
 & [1.0, 2.8] & $8\rho $\rule{.25in}{0pt}\\
 & [2.8, 4.0] & $16\rho $\rule{.25in}{0pt}\\
 & [4.0, 5.7] & $32\rho $\rule{.25in}{0pt}\\
 & [5.7, 8.0] & $64\rho $\rule{.25in}{0pt}\\
 & [8.0, 8.6] & $128\rho $\rule{.25in}{0pt}\rule[-7pt]{0pt}{8pt}\\
SERFCE & [0, 2] & $4\rho $\rule{.25in}{0pt}\\
& [2, 4] & $8\rho $\rule{.25in}{0pt}\\
& [4, 50] & $2\rho $\rule{.25in}{0pt}
\end{tabular}
\end{center}

The increase of relative error in SERFC with increasing arguments is an
inherent property of the erfc function.

\bibliographystyle{math77}
\bibliography{math77}

\subsection{Error Procedures and Restrictions}

The argument for SERFCE or DERFCE must be nonnegative. If it is negative the
subprogram will issue an error message and return a zero result.

If the argument for SERFC or DERFC exceeds XMAX, defined above in Section D,
the subroutine will issue a warning message and return a zero result.

Error and warning messages are processed using the subroutines of
Chapter~19.2 with an error level of zero.

\subsection{Supporting Information}

\begin{tabular}{@{\bf}l@{\hspace{5pt}}l}
\bf Entry & \hspace{.35in} {\bf Required Files}\vspace{2pt} \\
DERF & \parbox[t]{2.7in}{\hyphenpenalty10000 \raggedright
AMACH, DCSEVL, DERF, DERM1, DERV1, DINITS, ERFIN, ERMSG, IERM1, IERV1\rule[-5pt]{0pt}{8pt}}\\DERFC & \parbox[t]{2.7in}{\hyphenpenalty10000 \raggedright
AMACH, DCSEVL, DERF, DERM1, DERV1, DINITS, ERFIN, ERMSG, IERM1, IERV1\rule[-5pt]{0pt}{8pt}}\\DERFCE & \parbox[t]{2.7in}{\hyphenpenalty10000 \raggedright
AMACH, DCSEVL, DERF, DERM1, DERV1, DINITS, ERFIN, ERMSG, IERM1, IERV1\rule[-5pt]{0pt}{8pt}}\\SERF & \parbox[t]{2.7in}{\hyphenpenalty10000 \raggedright
AMACH, ERFIN, ERMSG, IERM1, IERV1, SCSEVL, SERF, SERM1, SERVI, SINITS\rule[-5pt]{0pt}{8pt}}\\SERFC & \parbox[t]{2.7in}{\hyphenpenalty10000 \raggedright
AMACH, ERFIN, ERMSG, IERM1, IERV1, SCSEVL, SERF, SERM1, SERVI, SINITS\rule[-5pt]{0pt}{8pt}}\\SERFCE & \parbox[t]{2.7in}{\hyphenpenalty10000 \raggedright
AMACH, ERFIN, ERMSG, IERM1, IERV1, SCSEVL, SERF, SERM1, SERVI, SINITS\rule[-5pt]{0pt}{8pt}}\\\end{tabular}

Based on a 1977 program by L. W. Fullerton, Los Alamos, and a 1969 program
by E. W. Ng, JPL. Present version by C. L. Lawson and S. Y. Chiu, JPL, 1983.

\begcodenp
\medskip\
\lstset{language=[77]Fortran,showstringspaces=false}
\lstset{xleftmargin=.8in}

\centerline{\bf \large DRSERF}\vspace{10pt}
\lstinputlisting{\codeloc{serf}}
\newpage

\vspace{30pt}\centerline{\bf \large ODSERF}\vspace{10pt}
\lstset{language={}}
\lstinputlisting{\outputloc{serf}}

\closegraphsfile
\end{document}


\documentclass[11pt]{article}
%Gummi|065|=)
\title{\textbf{Algorithms in Julia}}
\author{Valentin Churavy \and James Schloss}
\date{}

\usepackage{graphicx}
\usepackage{hyperref}
\usepackage{listings}
\usepackage{color}

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

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

\begin{document}
\maketitle
In this document, we have descriptions of the following algorithms:
\begin{itemize}
\item Monte Carlo
\item Split-Operator method for solving the Schrodinger Equation
\item Julia Fractal
\item Force Integration with Verlet integration
\item Barnes-Hut (N-body galaxy simulation)
\item Euler Method
\item Subsetting Dataframes
\item Auto-Differentiation
\end{itemize}

All algorithms can be found in the examples directory of the \texttt{skillpill-julia} repository on github

\newpage
\section*{Monte Carlo}

There are many different methods that all work under the basic Monte Carlo principle of using random numbers to integrate systems.
For the sake of time and brevity, please refer to the following link for more information on Monte Carlo integration: \url{https://www.algorithm-archive.org/contents/monte_carlo_integration/monte_carlo_integration.html}. From there, modify the provided code to integrate $x^2$ where $-3 < x < 3$.

My function reads in a total range in x along with the number of points to sample. Try to match (or beat) the following benchmark:

\begin{lstlisting}
julia> @benchmark monte_carlo(6.0, 100000)
BenchmarkTools.Trial:
  memory estimate:  0 bytes
  allocs estimate:  0
  --------------
  minimum time:     573.931 s (0.00% GC)
  median time:      578.105 s (0.00% GC)
  mean time:        596.870 s (0.00% GC)
  maximum time:     1.125 ms (0.00% GC)
  --------------
  samples:          8326
  evals/sample:     1

\end{lstlisting}

\newpage
\section*{Split-Operator Method}
The Split-Operator Method is a psuedo-spectral method that is important for many areas of physics, including quantum mechanics, where it is used to solve the Schr\"odinger equation,

$$
i \hbar \frac{\partial \Psi(\mathbf{r}, t)}{\partial t} = \left[\frac{-\hbar^2}{2m} \nabla^2 + V(\mathbf{r},t) \right] \Psi(\mathbf{r},t)
$$

To solve this equation, we basically split the time evolution operator ($\hat U = e^{-i \hat H t / \hbar}$) into 2 via the Baker-Campbell-Hausdorff relation:
$$\hat U_k = e^{-\mathbf{\hat p}^2 t / 2} \quad \hat U_V = e^{-V_0(\mathbf{\hat r})t/2}$$

From here, the method simply involves initializing the wavefunction and then multiplying it by half of $\hat U_V$ before flipping to momentum space via a FFT and multiplying it by all of $\hat U_k$ and then flipping back to real space with an inverse FFT and multiplying by the other half of $\hat U_V$, as shown in figure \ref{fig:split-op}.

More information can be found here: \url{https://www.algorithm-archive.org/contents/split-operator_method/split-operator_method.html}

\begin{figure}
\begin{center}
\includegraphics[width = 0.5\textwidth]{split-op.png}
\end{center}
\caption{A single step in the split-op method as described in the description}
\label{fig:split-op}
\end{figure}

\newpage
\section*{Julia Fractal}
Fractals are cool. They are structures that continually repeat themselves no matter how far you zoom in. Because we are using Julia, the obvious fractal to work with is the Julia fractal. Full implementation details in Python can be found here: \url{https://batchloaf.wordpress.com/2013/02/10/creating-julia-set-images-in-python/}. Basically, all we need to do is iteratively solve the following formula:
$$z_{n+1} = z_n^2 + c$$
Every iteration, we reduce pixel color by 5 and recalculate z until either the pixel color is 0 or $|z|$ exceeds a provided cutoff value (somewhat arbitrary). It should be noted here that $c$ is entirely complex and that the value dratically changes the output fractal.

Create the following:
\begin{enumerate}
\item A function that sweeps through different $c$ values and outputs an image for each value
\item A function that zooms into a fractal of $c=1.0$ to see it's self-similar nature
\end{enumerate}

If you want to, you can even combine the images into a gif by using some additional tool (like ffmpeg)
\begin{figure}
\begin{center}
\includegraphics[width=0.45\textwidth]{fractal_zoom00030.png}
\includegraphics[width=0.45\textwidth]{c_scan00030.png}
\end{center}
\end{figure}

\newpage
\section*{Force Integration}
Integrating forces is a staple of any physics engine and most physics simulations. Though there are many different algorithms to do this, here we focus on the Verlet algorithm (because it's conceptually simple); however, if you want to implement Runge-Kutta (or whatever), feel free to do so!

First, let's start with the Taylor Series expansion:

$$x = x_0 + v_0 t + \frac{1}{2}at^2 + \ldots$$

If we are looking for $x(t + \Delta t)$, we can start by looking at the timesteps immediately before it:
$$x(t+\Delta t) = x(t) + v \cdot \Delta t + \frac{1}{2} a\cdot\Delta t^2$$
$$x(t-\Delta t) = x(t) - v \cdot \Delta t + \frac{1}{2} a\cdot\Delta t^2$$

Adding these together and solving for $x(t + \Delta t)$, we get:

$$x(t + \Delta t) = 2x(t) - x(t - \Delta t) + a \Delta t^2$$

This means we can solve for any object's new position if we know it's acceleration and where it's been! Of course, if we need the velocity (possibly to solve for the acceleration of a damped system), we can find it with:

$$v(t) = \frac{x(t + \Delta t) - x(t - \Delta t)}{2\Delta t}$$

Now, let's integrate some forces! Start with a ball at a height of 5m. How long does it take to hit the ground? Also, plot it's trajectory with time.

\newpage
\section*{Barnes-Hut}
Using the previous section on force integration, we know that all we really need for an N-body gravity simulator is a method to calculate the acceleration of an object in space. In principle, this is straightforward: We just add up all the particles and calculate

$$a = \frac{GMm}{r^2}$$

In practice, this means that we have an $O(n^2)$ problem on our hands! That said, we can take our N-body simulation and speed it up drastically with the help of a rather famous data structure known as an octree (or quadtree in 2d).

These data structures are straightforward. The root node is the entire simulation box, it's children are the octants of that box. Each octant has 8 octchildren, and we keep splitting up the simulation until every particle has it's own box. At this point, it's not obvious how this speed anything up; however, each box has a Center of Mass equal to all the elements on the inside of it. If our objects are sufficiently far away from each other, we can take a larger parent box instead of a smaller child box. This cuts computational time tremendously!

In particular, the cutoff value is defined as $\theta = s/d$ where $s$ is the width of the region represented by the internal node and $d$ is the distance between the body and it's Center of Mass. By playing with $\theta$, we can have either a fast, inaccurate simulation or a slow, accurate one. The trick is finding the happy-medium between the two!

\newpage
\section*{Euler Method}

Euler methods are some of the simplest methods for solving ordinary differential equations. For the purposes of this Skill Pill, we will only be implementing the forward Euler method, which is notably unstable with certain step sizes. Rather than doubling-up work that has already been done, please go to \url{https://www.algorithm-archive.org/contents/forward_euler_method/forward_euler_method.html}, and read up about the euler method there. There is even a Julia implementation available on the page if you are struggling to figure out how to do the implementation!

Admittedly, the primary author of the Algorithm Archive only solved a simple ODE: $y(t)' = -3t$; however, the method can easily be extended to other, more difficult equations!

\newpage
\section*{Subsetting Dataframes}

For many applications in computational science, it is important to learn how to appropriately use data frames. This was somewhat discussed earlier whith the \texttt{DelimitedFiles} and \texttt{CSV} packages; however, Julia should have all the features of other languages that are known for data frame manipulation, such as R.

To use a data frame, we first need to load the DataFrames package with \texttt{using DataFrames}. All of the documentation can be found here: \url{https://testdataframesjl.readthedocs.io/en/readthedocs/}. For this exercise, we will be a simple example of subsetting, which is a process of grabbing only a subset of the overall data frame. There is a lot more information about what is possible in the documentation, so feel free to mess around as you please!

In general, creating a data frame follows similar notation to creating arrays in Julia. If we wanted to create a matrix that has 3 columns (A, B, and C), all of which have different information, we might use the following command:

\begin{lstlisting}
df = DataFrame(A = 1:10, B = 2:2:20, C = (1:10).^2)
\end{lstlisting}

Which will create the following data frame:

\begin{lstlisting}
10x3 DataFrame
 Row  A      B      C
      Int64  Int64  Int64
 1    1      2      1
 2    2      4      4
 3    3      6      9
 4    4      8      16
 5    5      10     25
 6    6      12     36
 7    7      14     49
 8    8      16     64
 9    9      18     81
 10   10     20     100

\end{lstlisting}
Continued on next page...

\newpage
Here, we can grab particular elements by using the following operations:

\begin{lstlisting}
df[:B]   <- B column
df[1,2]  <- Row 1, column B
df[1:3] <- Rows 1-3
df[1:3, [:C,:A]] <- Columns C and A, rows 1-3
df[df[:A].%2 .== 0,:] <- all rows where A is even
\end{lstlisting}

so here is a quick problem set:

\begin{enumerate}
\item Create a data frame similar to the one created here
\item Use all the provided commands on the data frame
\item Turn all elements in column A to even by adding or subtracting 1 from all odd elements
\end{enumerate}

\newpage
\section*{Auto-differentiation}

I admittedly do not know much about auto-differentiation, but I plan to learn more. The purpose of this exercise is not to explain the theory of what auto-differentiation is or why it is important. Rather, this exercise intends to provide a succint description of auto-differentiation in Julia. For the most part, this is done with the \texttt{ForwardDiff.jl} package. The most up-to-date documentation can be found here: \url{http://www.juliadiff.org/ForwardDiff.jl/latest/index.html}.

The package provides Derivatives, Gradients, Hessians, and Jacobians, but for the purposes of this example, we will simply deal with derivatives.

Here is an example for doing a derivation of $f(x) = x^2$:

\begin{lstlisting}
f(x) = x^2
ForwardDiff.derivative(f,2)
\end{lstlisting}

This should output $4$ because $\frac{df(x)}{dx} = 2x$ and $2\times2 = 4$.

\vspace{1cm}

To get the hang of things from here, please compute the derivative of $\sin(x)$, evaluated at $x = 0$.

\vspace{1cm}

From there, please explore what you can do with the package and try to compute whatever derivatives you see fit!

\end{document}