\section{Datasets}

\subsection{Visibility Datasets}
\label{sec:vis}

Visibility datasets in UVF format are currently supported (I have a
stub for miriad file format and the code to read it exists, but it is
not yet implemented), by using \code{adddataset} with \code{type =
  uvf}, i.e.:

\begin{myindentpar}{3cm}
adddataset type=uvf name=duvf;
\end{myindentpar}

On read-in, visibility data are automatically gridded in Fourier space
by unique baseline type (for heterogeneous array data) and frequency.
By default the size of the Fourier grid (effective resolution in image
space) is chosen for each baseline/frequency combination according to
the maximum uv radius present in the data.  The resolution in Fourier
space (effective size in image space) is chosen so that the integrated
overlap of the autocorrelation functions (what I refer to as the {\it
  correlation percentage}) for visibility data in each cell is at
least \code{perc}.  This defaults to $95\%$, or
$\code{duvf.perc=0.95}$.  The automated gridding will, in general,
result in different model and primary beam resolution for each
baseline/frequency pair, and Fourier transforms that are not square,
leading to the fastest performance for image-plane models that require
Fourier inversion.

Although dirty images are produced for visibility datasets as if the
array were homogeneous (i.e., no correction is made for the different
primary beams), the fitting is handled correctly for heterogeneous
data as well.  If you want to make beam-corrected images (as for a
mosaic) of a heterogeneous dataset, use the mosaicked dataset type
instead (see \S\ref{sec:mosaic} below).

For heterogeneous data, antennas can be included/excluded by type (if
the type can be determined from the data), or by antenna number.  Thus

\begin{myindentpar}{3cm}
duvf.useanttypes = sza,bima;
\end{myindentpar}

would cause \climax\ to use only data from SZA and BIMA antennas in a
CARMA23 dataset, and

\begin{myindentpar}{3cm}
duvf.excludeants = 1,4;
\end{myindentpar}

would use only data matching any specified type, and not including
antennas 1 or 4.

\subsubsection{Making Images of Visibility Data}

Data can also be gridded to a fixed resolution if desired, though this
is not recommended for running chains, since there is no guarantee
that the correlation percentage is uniform, or that the data are
gridded to the minimum required transform size.  It can however be
useful for producing images of visibility datasets at fixed
resolution.  For example, to produce a $128\times128$-pixel image that
is 0.3 degrees on the sky, you can do:

\begin{myindentpar}{3cm}
adddataset type=uvf name=duvf;\\
duvf.size = 0.3 degrees;\\
duvf.npix = 128;\\
duvf.display = true;
\end{myindentpar}

To select a uv range for imaging or fitting in a Markov chain, use the
\code{uvmin} and \code{uvmax} parameters:

\begin{myindentpar}{3cm}
duvf.uvmin = 0;\\
duvf.uvmax = 2000;
\end{myindentpar}

This would apply a cutoff at $2~k\lambda$ when gridding the visibility
data.  You can also apply a uvtaper to the data for imaging, but it is
not recommended for fitting, since it changes the likelihood ratio
associated with a given $\Delta\chi^2$.  For example:

\begin{myindentpar}{3cm}
duvf.uvtaper = 0.5, 2000;
\end{myindentpar}

would apply a gaussian uvtaper whose half-power point lies at
$2~k\lambda$.

For all visibility datasets you can have \climax\ output the
data/model/residual images as FITS files by using the
\code{dataimage/modelimage/resimage} keywords.

\subsubsection{Dirty Maps and Pixel Covariance}

When we form a dirty map by Fourier transform of the visibilities, for
each pixel $j$ we construct the sum:

\begin{eqnarray}\nonumber
d_j &=& \int\int\widetilde{V}(u,v)e^{2\pi i(ux_j + vy_j)}du\,dv\\\nonumber
    &=& \int_{\it HP}\left\{\widetilde{V}(u,v)e^{2\pi i(ux_j + vy_j)} + \widetilde{V}(-u,-v)e^{-2\pi i(ux_j + vy_j)}\right\}\\
    &=& \int_{\it HP}\left\{\widetilde{V}(u,v)e^{2\pi i(ux_j + vy_j)} + \widetilde{V}^*(u,v)e^{-2\pi i(ux_j + vy_j)}\right\}
\label{eq:dirtyint}
\end{eqnarray}

where the integral is over the half-plane, and the last step assumes
that the Fourier transform is Hermitian.  If we rewrite the transform
as a discrete sum, we have:

\begin{eqnarray}\nonumber
  d_j &=& \sum_k{\left\{\left(V^R_k + iV^I_k\right)\left\{\cos(a_{jk}) + i\sin(a_{jk})\right\} + \left(V^R_k - iV^I_k\right)\left\{\cos(a_{jk}) - i\sin(a_{jk})\right\}\right\}}\\
    &=& \sum_k{\left\{V^R_k\cos(a_{jk}) - V^I_k\sin(a_{jk})\right\}}
\end{eqnarray}

up to a normalization (with $a_{jk} = 2\pi(x_ju_k + y_jv_k)$).  For maps made with ``natural
weighting'', we form the dirty map from the weighted mean of the
visibilities

\begin{equation}
d_j = {{\sum_k{w_kV^R_k}\cos(a_{jk}) - \sum_k{w_kV^I_k}\sin(a_{jk})}\over{\sum_k{w_k}}},
\label{eq:dirtysig}
\end{equation}

with $w_k = 1/\sigma^2_k$, i.e., the inverse variance of the Re/Im
part of the visibility (since that is the estimator that maximizes the
likelihood of our visibility data).  What is the variance of
$\{d_j\}$?  It's given by

\begin{eqnarray}\nonumber
\sigma^2 \equiv\ <d_j^2> &=& {{\sum_k{w^2_k\left<{V^R_k}^2\right>\cos^2(a_{jk})} + \sum_k{w^2_k\left<{V^I_k}^2\right>\sin^2(a_{jk})}\over{\left(\sum_k{w_k}\right)^2}}}\\\nonumber
&=& {{{\sum_k{w^2_k\sigma^2_k{\cos^2(a_{jk})}}} + \sum_k{w^2_k\sigma^2_k{\sin^2(a_{jk})}}}\over{\left(\sum_k{w_k}\right)^2}}\\
&=& {{\sum_k{w^2_k\sigma^2_k}}\over{\left(\sum_k{w_k}\right)^2}} = {{\sum_k{w_k}}\over{\left(\sum_k{w_k}\right)^2}} = {{1}\over{\sum_k{w_k}}}
\label{eq:dirtyvar}
\end{eqnarray}

\subsubsection{Synthesized beam}

From examination of Eqs.~\ref{eq:dirtyint} and
Equation~\ref{eq:dirtysig}, it is clear that we can express the
discrete sampling of the Fourier transform as the multiplication of
$\widetilde{V}$ with a sampling function $\widetilde{W}$, where

\begin{equation}
\widetilde{W} = {{\sum_k \delta(u_k, v_k) w_k}\over{\sum_k w_k}}.
\end{equation}

By the convolution theorem, the inverse transform $W \equiv
\mathcal{F}^{-1}\{\widetilde{W}\}$ therefore represents the function by which the sky
signal has been convolved, or effectively the point-spread function of
the interferometer.  This function is commonly referred to as the {\it
  synthesized beam}, and can have significant spatial sidelobe
structure compared to a typical filled-aperture instrument, due to its
sharp discontinuities in Fourier space.

\subsubsection{Estimating the clean beam width}

We want a gaussian approximation to the synthesized beam.

A gaussian approximation to any function can be calculated from considering the Taylor expansion of its logarithm:

\begin{equation}
\ln f(x) \simeq \ln f(x_0) - \left.\pd{\ln f}{x}\right|_{x_0}(x - x_0) + {1\over{2}}\left.\pdd{\ln f}{x}\right|_{x_0}(x - x_0)^2 + \dots
\end{equation}

Since we are expanding about the maximum, $\left.{\pd{\ln f}{x}}\right|_{x_0} = 0$, and

\begin{equation}
\ln f(x) \simeq \ln f(x_0) + {1\over{2}}\left.\pdd{\ln f}{x}\right|_{x_0}(x - x_0)^2 + \dots
\end{equation}

To the extent that we can ignore higher-order terms in the expansion,
the function will be dominated by the quadratic term, and we can write

\begin{equation}
f(x) \simeq f(x_0) \exp\left({1\over{2}}\left.\pdd{\ln f}{x}\right|_{x_0}(x - x_0)^2\right)
\end{equation}

which is just a Gaussian of width

\begin{equation}
\sigma_x = \left(-\left.\pdd{\ln f}{x}\right|_{x_0}\right)^{-1/2}.
\label{eq:gapprox}
\end{equation}

To calculate the gaussian approximation to the synthesized beam, we
start with the (1D) expression for the synthesized beam:

\begin{equation}
W(x) = {{\sum_k{w_k}\cos(2\pi x u_k)}\over{\sum_k{w_k}}}
\end{equation}

whence

\begin{equation}
\ln W(x) = \ln{\sum_k{w_k}\cos(2\pi x u_k)} + \ln\sum_k{w_k},
\end{equation}

\begin{equation}
{\pd{\ln W(x)}{x}} = -{{2\pi\sum_k{w_k u_k\sin(2\pi x u_k)}}\over{\sum_k{w_k\cos(2\pi x u_k)}}}
\end{equation}

and

\begin{equation}
{\pdd{\ln W(x)}{x}} = -{{(2\pi)^2\sum_k{w_k u^2_k\cos(2\pi x u_k)}}\over{\sum_k{w_k\cos(2\pi x u_k)}}} + {{(2\pi)^2\left(\sum_k{w_k u_k\sin(2\pi x u_k)}\right)^2}\over{\left(\sum_k{w_k\cos(2\pi x u_k)}\right)^2}}.
\end{equation}

When we evaluate this at zero, the $\sin$ terms vanish, and we are left with:

\begin{equation}
\sigma = {1\over{\sqrt{2\pi^2\left<u^2\right>}}}
\end{equation}

with

\begin{equation}
\left<u^2\right> \equiv {{\sum{u^2_k w_k}}\over{\sum{w_k}}}.
\end{equation}

\subsubsection{Clean images}

Rewriting $\Delta V_k \equiv V^R_k cos(a_{jk}) - V^R_k sin(a_{jk})$,
we see that if we divide the visibilities into subsets, we have:

\begin{eqnarray}
d_j &=& {{\sum_{k1}{w_{k1}\Delta V_{k1}} + \sum_{k2}{w_{k2}\Delta V_{k2}}}\over{\sum_{k1}{w_{k1}} + \sum_{k2}{w_{k2}}} }\\
    &=& {{\sum_{k1} w_{k1}}\over{\sum_k w_k}}{{\sum_{k1}{w_{k1}\Delta V_{k1}}}\over{\sum_{k1}w_{k1}}}
+ {{\sum_{k2} w_{k2}}\over{\sum_k w_k}}{{\sum_{k2}{w_{k2}\Delta V_{k2}}}\over{\sum_{k2}w_{k2}}}\\
&=& {{\sum_{i}{w_i d_{\ij}}}\over{\sum_{i}{w_i}}},
\label{eq:dirtysum}
\end{eqnarray}

that is, the combined dirty map is the weighted sum of the individual
dirty maps, with $w_i$ given by the sum of the weights for each subset
of visibilities.

What is generally referred to as a {\it clean} image is the equivalent
sky signal that would be seen by a filled aperture instrument with
resolution equivalent to the main lobe of the synthesized beam.  We
can use Eq.~\ref{eq:dirtysum} to construct this image in the same way
as the dirty image, but with $d_{\ij}$ replaced by the model convolved
with a Gaussian approximation to the synthesized beam, i.e.:

\begin{equation}
c_j = {{\sum_{i}{w_i c_{\ij}}}\over{\sum_{i}{w_i}}} + r_j
\end{equation}

where $c_{\ij} = \{M * \hat{W_i}\}_j$, i.e., the model convolved with the
$i^{th}$ approximate PSF, and $r_j$ is the residual image, obtained
from Eq.~\ref{eq:dirtysig} by replacing $\tilde{V}_k$ with the delta
between the data and model, i.e., $\tilde{V}^m_k - \tilde{V}^d_k$.

Two different types of clean images can be made in \climax: an image
where the model to be convolved with the synthesized beam is taken
from the parameter file (or best-fit model from a Markov chain), or an
image where the model is built up iteratively out of delta functions
via the {H{\"o}gbom} CLEAN algorithm \citep{1974A&AS...15..417H}.

The type of clean image to produce is controlled by the \code{clean}
and \code{cleantype} keywords.  If \code{clean = true} then a clean
image will be generated in place of the default model image.  To
produce the first type of clean image, use:

\begin{myindentpar}{3cm}
adddataset type=uvf name=vis;\\
vis.clean = true;\\
vis.cleantype = model;\\
\end{myindentpar}

Note that this will construct an image using an equivalent
filled-aperture synthesized beam.  As-such, if your model contains
large-scale power that is not sampled by the actual (i.e., incomplete
Fourier sampling) instrument, then your clean image will also contain
large-scale power that is not present in the dirty maps.

An alternative is the H{\"o}gbom algorithm, which iteratively
  constructs a model from the dirty maps using only delta-function
  components; i.e., it is a filled-aperture model approximation to the
  structure seen in the dirty maps using only components that the
  actual instrument has sensitivity to.  This can be requested by
  specifying \code{cleantype = delta} instead.

The H{\"o}gbom algorithm works by iteratively finding the highest
peaks in the dirty map, at each step in the iteration subtracting a
copy of the synthesized beam, whose amplitude is a fraction of the
flux at that location.  The iteration proceeds until a specific cutoff
flux is reached, or the maximum number of iterations is reached if no
cutoff is specified.

The number of iterations is controlled by the \code{cleaniter}
keyword.  The fraction of the synthesized beam to subtract at each
step is specified by the \code{cleangain} keyword.  A cutoff threshold
(in Jy) can be specified using the \code{cleancutoff} keyword.

Additionally, the user must specify windows that the clean algorithm
will search.  You can specify clean windows in a couple different ways:

\begin{myindentpar}{3cm}
cleanwindow = [abs +- 0.01, abs +- 0.01, deg];
\end{myindentpar}

sets up a clean window of $\pm 0.1$~deg around the position of the
absolute maximum.  You can also use \code{max} or \code{min} instead
of \code{abs}.  Similarly

\begin{myindentpar}{3cm}
cleanwindow = [-2:2, -2:2, '];
\end{myindentpar}

sets up an arbitrary rectangle window.  Lastly, you can use:

\begin{myindentpar}{3cm}
cleanwindow += [-2:2, -2:2, '];
\end{myindentpar}

to set up more than one window.

\subsection{Writing Visibility Datasets}
\label{sec:viswrite}

Data, model or residual visibilities can be written out using the
\code{datauvf}, \code{modeluvf} or \code{resuvf} keywords, in
combination with the \code{writedata} directive.  Note that the
dataset's \code{store} keyword must be set to true to use this
function.

For unstacked visibility data, all data (including flagged or
unselected visibilities) are written, with weights as in the original
file.

For stacked data, only unflagged data matching your current selection
criteria (selected IFs, antennas or UV range) will be written out,
with any requested weight scaling applied to the data.

\subsection{Stacking Visibility Datasets}
\label{sec:stack}

For each dataset, we construct the weighted mean of each visibility according to:

\begin{equation}
\hat{V}_k = {{\sum{V_j w_{\jk}}\over{\sum{w_{\jk}}}}}
\end{equation}

When combining datasets for which estimators $\hat{V}_k$ have already
been formed, we ultimately want:

\begin{eqnarray}\nonumber
\hat{V} &=& {{\sum_k\sum_j{V_j w_{\jk}}\over{\sum_k\sum{w_{\jk}}}}}\\\nonumber
        &=& {{\sum_k\hat{V}_k\sum{w_{\jk}}}\over{\sum_k\sum{w_{\jk}}}}\\\nonumber
        &=& {{\sum_k\hat{V}_k W_k}\over{\sum_k W_k}}\\\nonumber.
\end{eqnarray}

In other words, the combined maximum likelihood estimator for $V$ is
just the weighted mean of the separate estimators $\hat{V}_k$, with
weights $W_k = \sum{w_{\jk}}$.

From Eq.~\ref{eq:dirtysum}, we see that if we break up the
visibilities into subsets, the combined dirty map can be written as
the weighted sum of the dirty maps from each subset.  If the subsets
of visibilities represent different observations with the same
pointing, the result is trivially the dirty map you would obtain by
combining the visibilities and Fourier-transforming.

What if the subsets of visibilities represent offset pointings?  By
shifting each subset of visibilities to a common center, we can
construct a dirty map that has the correct center, but the primary
beam envelope for each subset will now be shifted with respect to the
others, i.e.

\begin{equation}
d_j = {{\sum_{i}{w_i d_{\ij}}}\over{\sum_{i}{w_i}}},
\end{equation}

but

\begin{equation}
d_{\ij} = b_{\ij} s_j + n_{\ij},
\end{equation}

where

\begin{equation}
b_{\ij} = b(x_j + \Delta x_i, y_j + \Delta y_i).
\end{equation}

Thus the dirty image is the sky signal multiplied by an effective primary beam $\bar{b}_j$, where

\begin{equation}
\bar{b}_j = {{\sum_i{w_i\,b(x_j + \Delta x_i, y_j + \Delta y_i)}}\over{\sum_i{w_i}}}.
\end{equation}

\subsection{Mosaicked Visibility Datasets}
\label{sec:mosaic}

Mosaicked visibility datasets can also be handled in \climax, by using the
by using \code{adddataset} with \code{type = mos}, i.e.:

\begin{myindentpar}{3cm}
adddataset type=mos name=dmos;
\end{myindentpar}

Once defined, datasets can be added to the mosaic using the \code{file} keyword:

\begin{myindentpar}{3cm}
\begin{verbatim}
dmos.file  = MS0735_p1.uvf;
dmos.file += MS0735_p2.uvf;
\end{verbatim}
\end{myindentpar}

The mosaic dataset supports the same set of keywords as the \code{uvf}
visibility dataset (e.g., \code{wtscale, uvmin, uvmax}) plus some
additional ones, primarily for mapmaking.

Use the keyword \code{power} to specify the point of the primary beam
beyond which images for each antenna pair/frequency combination will
be masked before coadding to make the final mosaicked map.

Use the keyword \code{wtmin} to set the minimum weight in the combined
map.  The final image will be truncated at the boundary beyond
which the weight is below this limit.

These keywords have no effect on fitting of mosaicked data in \climax.

Note that when using the mosaicked dataset, you will in general need
to specify absolute coordinates (RA/DEC) for any models, so that the
relative separations from the RA/DEC of component datasets are
correctly accounted for.

\subsubsection{Mosaicking Theory}

The ``dirty image'' from an interferometer is enveloped by the primary
beam of the antennas.  As such, if $d_\ij$ represents the intensity
in pixel $j$ of map $i$, we have

\begin{equation}
d_{\ij} = b_{\ij}s_j + n_{\ij},
\label{eq:mosmap}
\end{equation}

that is, the pixel consists of the sky signal $s_j$, multiplied by the
$i$th beam at location $j$, $b_{\ij}$, plus some additive noise.  We
wish to form the weighted mean of the true sky signal at each pixel,
or:

\begin{equation}
\hat{s}_{\ij} = d_{\ij}/b_{\ij},
\end{equation}

with variance

\begin{equation}
\sigma^2_{\hat{s}_{\ij}} = \sigma^2_i/b^2_{\ij},
\end{equation}

where $\sigma^2_i$ is given by Eq.~\ref{eq:dirtyvar}.  Thus the $j$th
pixel in the mosaicked map is given by:

\begin{eqnarray}
\hat{s}_j &=& {{\sum_i{\hat{s}_{\ij}/\sigma^2_{\hat{s}_{\ij}}}}\over{\sum_i{1/\sigma^2_{\hat{s}_{\ij}}}}}\\
          &=& {{\sum_i{b_{\ij}d_{\ij}/\sigma^2_i}}\over{\sum_i{b^2_{\ij}/\sigma^2_{i}}}}.
\label{eq:signal}
\end{eqnarray}

The uncertainty on the weighted mean sky signal in each pixel is given
by the variance of Eq.~\ref{eq:signal}:

\begin{equation}
V\left[{{\sum_i{b_{\ij}d_{\ij}/\sigma^2_i}}\over{\sum_i{b^2_{\ij}/\sigma^2_i}}}\right] =
{{\sum_i{V\left[b_{\ij}d_{\ij}/\sigma^2_i\right]}}\over{\left(\sum_i{b^2_{\ij}/\sigma^2_i}\right)^2}} =
{{\sum_i{V[b_{\ij}d_{\ij}]/\sigma^4_i}}\over{\left(\sum_i{b^2_{\ij}/\sigma^2_i}\right)^2}} =
{{\sum_i{b^2_{\ij}/\sigma^2_i}}\over{\left(\sum_i{b^2_{\ij}/\sigma^2_i}\right)^2}} =
{{1}\over{\sum_i{b^2_{\ij}/\sigma^2_i}}},
\end{equation}

or

\begin{equation}
\sigma^2_{\hat{s}_j} = {{1}\over{\sum_i{b^2_{\ij}/\sigma^2_i}}},
\label{eq:noise}
\end{equation}

with \snr\ given by:

\begin{equation}
{\hat{s}_j}/\sigma_{\hat{s}_j} = {{\sum_i{b_{\ij}d_{\ij}/\sigma^2_i}}\over{\sqrt{\sum_i{b^2_{\ij}/\sigma^2_{i}}}}}.
\label{eq:snr}
\end{equation}

As for datasets of type \code{uvf} you can have \climax\ output the
data/model/residual images as FITS files by using the
\code{dataimage/modelimage/resimage} keywords (for \code{mos}
datasets, these will be in units of \snr\ instead of Jy/beam).  For
mosaicked data, you can additionally output the noise image in
Jy/beam, ($\sqrt{Eq.~\ref{eq:noise}}$) by using the keyword
\code{noiseimage}.

\subsubsection{Mosaicked clean images}

Equation~\ref{eq:signal} is the primary-beam corrected analog of
Equation~\ref{eq:dirtysum}.  We can construct a clean image in the
same way as before by replacing $d_{\ij}$ with $c_{\ij}$, the model
convolved with a Gaussian approximation to the synthesized beam.

If the H{\"o}gbom algorithm is used to construct a clean image, the
keyword \code{cleancutoff} for mosaicked datasets is interpreted as
\snr.

\subsection{Heterogeneous Visibility Datasets}

As discussed in \S\ref{sec:vis} above, heterogeneous interferometric
datasets are handled correctly by the default \code{uvf} dataset
type.  For imaging purposes, however, beam-corrected images of
heterogeneous datasets can be made by using the mosaicked datasets
type, \code{mos}, as discussed above.

Note that heterogeneous datasets can be treated in the same way as
mosaicked datasets, for mapmaking purposes.  In this case the beam
$b_{\ij}$ of Eq.\ref{eq:mosmap} represents the primary beam of each
distinct antenna pairing $i$ (and technically, at each individual
frequency) in the heterogeneous array (for three antenna types there
are 6), at the same spatial location $j$.

For the heterogeneous array, the beam for each pair consists of the
cross-product of the aperture fields of the two antenna types.  For
example, if the current grading across dishes $1$ and $2$ are $J_0$
Bessel functions (for some parameters $\rho$), then:

\begin{eqnarray}\nonumber
A_1(\theta) &=& \tilde{\mathcal{F}}(J_0(x, \rho_1))\\\nonumber
A_2(\theta) &=& \tilde{\mathcal{F}}(J_0(x, \rho_2))
\end{eqnarray}

where $\tilde{\mathcal{F}}$ denotes inverse Fourier transform, with primary beam given by

\begin{equation}
B_{12}(\theta) = A_1{A_2}^*,
\end{equation}

or

\begin{equation}
b_{\ij} = A_1(\theta_j){A_2(\theta_j)}^*,
\end{equation}

\subsection{Image Datasets}
\label{sec:image}

\subsubsection{Image Handling Basics}
\label{sec:imagehandling}

{\bf Reading Images}

For all image datasets or models, images can be read in FITS format,
either as standard FITS 2D images, or as columns from a FITS binary
table --- \climax\ attempts to detect the format automatically.  If a
binary table is detected, you will have to specify the binary table
extension from which the read the data (\code{im.extname}), and the x,
y and data columns of the table that comprise the image
((\code{im.xcol}), (\code{im.ycol}), and (\code{im.dcol}).  For
example:

\begin{myindentpar}{3cm}
im.extname = EVENTS;\\
im.xcol = x;\\
im.ycol = y;\\
im.dcol = energy;
\end{myindentpar}

would read an image from columns named \code{x}, \code{y} and
\code{energy} of the binary table with extension name \code{EVENTS}.

{\bf Sub-image Selection}

For all image datasets (or models), images can be manipulated on
readin, to extract a particular region, resample an image at a
different pixelation, smooth or otherwise transform the data.  For
example the following code:

\begin{myindentpar}{3cm}
im.region = 0,0 deg +- 0.1 deg;\\
\end{myindentpar}

would extract a $\pm 0.1$~deg region about the center position.  Note
that the \code{region} specification is somewhat complex and can take
many forms.  For example \code{im.region = 0,0 +- 0.1 deg} in the
example above would extract $\pm 0.1$~deg about {\it pixel} (0,0)
instead.  Specifying \code{region = 65:192,193:320} would extract an
subimage from pixel 65 to 192 in x and 193 to 320 in y, etc.  Parsing
a run file with an invalid region specification (i.e., \code{region =
  0}) will show valid usages.

{\bf Image Resampling}

Images can also be resampled after extraction, by using the
\code{npix} keyword.  Setting \code{im.npix = 128} would resample the
image to $128\times128$ pixels; setting \code{im.npix = 64 x 128}
would resample to $64\times128$.  To preserve the noise properties of
the image plane data, resampling is done by simple binning, rather
than convolution, which would correlate the pixel noise.  As a result,
for fitting purposes, you should not rebin an image with finer
resolution than the original, or you will duplicate pixels, and you
will generate sampling artifacts (i.e., moir\'e patterns) if you
resample an image by anything other than an integral divisor of the
original image sampling.

{\bf Image Smoothing}

For image models, images can be smoothed by convolution with a
gaussian kernel, by using the \code{sigmasmooth} keyword.  For example

\begin{myindentpar}{3cm}
im.sigmasmooth = 2'';
\end{myindentpar}

would convolve the extracted (and possibly resampled) image with
gaussian smoothing kernel of $\sigma = 2$~arcseconds.  Note that
smoothing by convolution is done via FFT, and the image should be
sampled to a power of 2, or you will produce unexpected artifacts.
You should not convolve image datasets, or you will produce correlated
pixel noise in the image plane.

{\bf Transforms}

Simple transformations can also be applied to images, by using the
\code{trans} keyword.  Setting \code{im.trans = sqrt} for example,
would take the square root of an image.  Setting \code{trans} to any
invalid transform name will show supported transform specifications.

\subsubsection{Generic Image Dataset}

Generic image-plane datasets, including support for point-spread
functions (PSF) can be defined by using \code{adddataset} with
\code{type = psfimage}.

Point-spread functions can be defined by using the \code{psf} keyword.  For example:

\begin{myindentpar}{3cm}
adddataset type=psfimage name=im;\\
im.file = myfile.fits;\\
im.psf = gauss;\\
im.obs.ant.diameter = 10m;\\
im.obs.freqs = 90 GHz;\\
im.obs.bws = 1 GHz;
\end{myindentpar}

would convolve all models with an approximate gaussian PSF
corresponding to a $10$~m antenna diameter at $90~$GHz.  Note that the
bandwidth is also required whenever a frequency is specified.  Using
\code{im.psf = realistic} calculates a more realistic primary beam by
assuming a uniform current grading across the specified aperture.
Using \code{psf = none} will compare models to the image data without
any intermediate convolution (the default if \code{psf} is not
specified).

Additionally, the \code{psfimage} dataset supports evaluation of
either Gaussian or Poisson likelihoods.  Poisson likelihood evaluation
may be more appropriate for data dominated by low-count Poisson
statistics (e.g., X-ray images).  The type of distribution to use can
be selected by using the \code{dist} keyword.  The default for
\code{psfimage} datasets is \code{dist = gauss}.

For Gaussian evaluation, a background (mean) and noise estimate (rms)
are required.  For Poisson evaluation, the background count rate is
required.

These can be specified either manually, via the \code{background} and
\code{noiserms} keywords, or you can specify a minimum radius for
estimating these quantities from the image by using the
\code{thetaMinErr} keyword, or you can specify a region from which to
estimate them, by using the \code{errRegion} keyword.

An additional parameter is provided, via the \code{errImage} keyword
for specifying whether quantities should be estimated from the
original image or from the extracted (and possibly resampled) image.
Think carefully about what you are doing here: if you are using
Poisson evaluation and you are resampling an image, the background
count rate should be estimated from the resampled image, or the
estimated background rate will not match the data.  Likewise, the
noise rms estimated for Gaussian evaluation must match the noise in
the final resampled image, or your statistics will not make sense.

Note that for Gaussian evaluation, the estimated background will be
subtracted from the image.

\subsubsection{Xray Image Dataset}

\climax\ also provides a specialization of the PSF dataset type for
x-ray image data, by using \code{adddataset} with \code{type = xrayimage}.
The extension is currently useful for fitting of cluster models, where
the shape of the cluster profile is inherently different for X-ray and
SZ observations.

Additionally, the \code{xrayimage} dataset defaults to Poisson
likelihood evaluation.

\subsubsection{Radio Image Dataset}

\climax\ also provides a specialization of the PSF dataset type for
radio image data, by using \code{adddataset} with \code{type = radioimage}.
The extension is currently useful for fitting of cluster models, where
the shape of the cluster profile is inherently different for X-ray and
SZ observations.


\documentclass[13pt,onlymath]{beamer}
\usefonttheme{serif}
\usepackage{graphicx,amsmath,amssymb,tikz,psfrag,epstopdf,fancyvrb}
\usepackage[lighttt]{lmodern}
%\usepackage{graphicx,psfrag}

\input defs.tex

%% formatting

\mode<presentation>
{
\usetheme{default}
}
\setbeamertemplate{navigation symbols}{}
\usecolortheme[rgb={0.13,0.28,0.59}]{structure}
\setbeamertemplate{itemize subitem}{--}
\setbeamertemplate{frametitle} {
    \begin{center}
      {\large\bf \insertframetitle}
    \end{center}
}

\newcommand\footlineon{
  \setbeamertemplate{footline} {
    \begin{beamercolorbox}[ht=2.5ex,dp=1.125ex,leftskip=.8cm,rightskip=.6cm]{structure}
      \footnotesize \insertsection
      \hfill
      {\insertframenumber}
    \end{beamercolorbox}
    \vskip 0.45cm
  }
}
\footlineon

\AtBeginSection[]
{
    \begin{frame}<beamer>
        \frametitle{Outline}
        \tableofcontents[currentsection,currentsubsection]
    \end{frame}
}

%% begin presentation

\title{\large \bfseries Shortest Path Algorithms}

\author{Jaehyun Park\\[3ex]
CS 97SI\\
Stanford University}

\date{\today}

\begin{document}

\frame{
\thispagestyle{empty}
\titlepage
}

\begin{frame}{Shortest Path Problem}
\BIT
\item Input: a weighted graph $G = (V, E)$
\BIT
\item The edges can be directed or not
\item Sometimes, we allow negative edge weights
\item Note: use BFS for unweighted graphs
\EIT
\item Output: the path between two given nodes $u$ and $v$ that minimizes the total weight (or cost, length)
\BIT
\item Sometimes, we want to compute all-pair shortest paths
\item Sometimes, we want to compute shortest paths from $u$ to all other nodes
\EIT \EIT
\end{frame}

\section{Floyd-Warshall Algorithm}

\begin{frame}{Floyd-Warshall Algorithm}
\BIT
\item Given a directed weighted graph $G$
\item Outputs a matrix $D$ where $d_{ij}$ is the shortest distance from node $i$ to $j$
\item Can detect a negative-weight cycle
\item Runs in $\Theta(n^3)$ time
\item Extremely easy to code
\BIT
\item Coding time less than a few minutes
\EIT
\EIT
\end{frame}

\begin{frame}{Floyd-Warshall Pseudocode}
\BIT
\item Initialize $D$ as the given cost matrix
\item For $k=1, \ldots, n$:
\BIT
\item For all $i$ and $j$:
\BIT
\item $d_{ij} := \min(d_{ij}, d_{ik}+d_{kj})$
\EIT \EIT
\item If $d_{ij} + d_{ji} < 0$ for some $i$ and $j$, then the graph has a negative weight cycle
\vfill
\item Done!
\BIT
\item But how does this work?
\EIT \EIT
\end{frame}

\begin{frame}{How Does Floyd-Warshall Work?}
\BIT
\item Define $f(i, j, k)$ as the shortest distance from $i$ to $j$, using nodes $1, \ldots, k$ as intermediate nodes
\BIT
\item $f(i, j, n)$ is the shortest distance from $i$ to $j$
\item $f(i, j, 0) = \mathrm{cost}(i, j)$
\EIT
\item The optimal path for $f(i,j,k)$ may or may not have $k$ as an intermediate node
\BIT
\item If it does, $f(i,j,k) = f(i,k,k-1) + f(k,j,k-1)$
\item Otherwise, $f(i,j,k) = f(i,j,k-1)$
\EIT
\item Therefore, $f(i,j,k)$ is the minimum of the two quantities above
\EIT
\end{frame}

\begin{frame}{How Does Floyd-Warshall Work?}
\BIT
\item We have the following recurrences and base cases
\BIT
\item $f(i,j,0) = \mathrm{cost}(i,j)$
\item $f(i,j,k) = \min(f(i,k,k-1)+f(k,j,k-1), f(i,j,k-1))$
\EIT
\item From the values of $f(\cdot, \cdot, k-1)$, we can calculate $f(\cdot, \cdot, k)$
\BIT
\item It turns out that we don't need a separate matrix for each $k$; overwriting the existing values is fine
\EIT
\item That's how we get Floyd-Warshall algorithm
\EIT
\end{frame}

\section{Dijkstra's Algorithm}

\begin{frame}{Dijkstra's Algorithm}
\BIT
\item Given a directed weighted graph $G$ and a source $s$
\BIT
\item Important: The edge weights have to be nonnegative!
\EIT
\item Outputs a vector $d$ where $d_i$ is the shortest distance from $s$ to node $i$
\item Time complexity depends on the implementation:
\BIT
\item Can be $O(n^2 + m)$, $O(m \log n)$, or $O(m + n \log n)$
\EIT
\item Very similar to Prim's algorithm
\item Intuition: Find the closest node to $s$, and then the second closest one, then the third, etc.
\EIT
\end{frame}

\begin{frame}{Dijkstra's Algorithm}
\BIT
\item Maintain a set of nodes $S$, the shortest distances to which are decided
\item Also maintain a vector $d$, the shortest distance estimate from $s$
\item Initially, $S:= \{s\}$, and $d_v := \mathrm{cost}(s, v)$
\item Repeat until $S = V$:
\BIT
\item Find $v \notin S$ with the smallest $d_v$, and add it to $S$
\item For each edge $v \rightarrow u$ of cost $c$:
\BIT
\item $d_u := \min(d_u, d_v+c)$
\EIT \EIT \EIT
\end{frame}

\section{Bellman-Ford Algorithm}

\begin{frame}{Bellman-Ford Algorithm}
\BIT
\item Given a directed weighted graph $G$ and a source $s$
\item Outputs a vector $d$ where $d_i$ is the shortest distance from $s$ to node $i$
\item Can detect a negative-weight cycle
\item Runs in $\Theta(nm)$ time
\item Extremely easy to code
\BIT
\item Coding time less than a few minutes
\EIT \EIT
\end{frame}

\begin{frame}{Bellman-Ford Pseudocode}
\BIT
\item Initialize $d_s:=0$ and $d_v:=\infty$ for all $v \ne s$
\item For $k=1, \ldots, n-1$:
\BIT
\item For each edge $u \rightarrow v$ of cost $c$:
\BIT
\item $d_v := \min(d_v, d_u+c)$
\EIT \EIT
\item For each edge $u \rightarrow v$ of cost $c$:
\BIT
\item If $d_v > d_u + c$:
\BIT
\item Then the graph contains a negative-weight cycle
\EIT \EIT \EIT
\end{frame}

\begin{frame}{Why Does Bellman-Ford Work?}
\BIT
\item A shortest path can have at most $n-1$ edges
\item At the $k$th iteration, all shortest paths using $k$ or less edges are computed
\item After $n-1$ iterations, all distances must be final; for every edge $u\rightarrow v$ of cost $c$, $d_v \le d_u+c$ holds
\BIT
\item Unless there is a negative-weight cycle
\item This is how the negative-weight cycle detection works
\EIT \EIT
\end{frame}

\begin{frame}{System of Difference Constraints}
\BIT
\item Given $m$ inequalities of the form $x_i - x_j \le c$
\item Want to find real numbers $x_1, \ldots, x_n$ that satisfy all the given inequalities
\vfill
\item Seemingly this has nothing to do with shortest paths
\BIT
\item But it can be solved using Bellman-Ford
\EIT \EIT
\end{frame}

\begin{frame}{Graph Construction}
\BIT
\item Create node $i$ for every variable $x_i$
\item Make an imaginary source node $s$
\item Create zero-cost edges from $s$ to all other nodes
\item Rewrite the given inequalities as $x_i \le x_j + c$
\BIT
\item For each of these constraint, make an edge from $j$ to $i$ with cost $c$
\EIT
\vfill
\item Now we run Bellman-Ford using $s$ as the source
\EIT
\end{frame}

\begin{frame}{What Happens?}
\BIT
\item For every edge $j\rightarrow i$ with cost $c$, the shortest distance $d$vector will satisfy $d_i \le d_j + c$
\BIT
\item Setting $x_i = d_i$ gives a solution!
\EIT
\item What if there is a negative-weight cycle?
\BIT
\item Assume that $1 \rightarrow 2 \rightarrow \cdots \rightarrow 1$ is a negative-weight cycle
\item From our construction, the given constraints contain $x_2 \le x_1 + c_1$, $x_3 \le x_2 + c_2$, etc.
\item Adding all of them gives $0 \le (\mbox{something negative})$
\item \ie, the given constraints were impossible to satisfy
\EIT \EIT
\end{frame}

\begin{frame}{System of Difference Constraints}
\BIT
\item It turns out that our solution minimizes the span of the variables: $\max x_i - \min x_i$
\item We won't prove it
\item This is a big hint on POJ 3169!
\EIT
\end{frame}

\end{document}


\documentclass{article}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{algpseudocode}
\title{Parallel Stitching}
\author{Dan Ibanez}
\date{Aug 20, 2014}
\begin{document}
\maketitle

\section{Theory}

This section outlines the theorical proof of the algorithm
to follow which sets up a partition model and remote
copy links from incomplete data for a distributed mesh.
It assumes a full one-level mesh representation with
correct partition model classification.

In a distributed mesh, each mesh entity of the entire mesh
resides on a set of parts.
If a mesh entity resides on a part, then a copy of it exists
in the mesh data structure of that part.
Let $\sim$ denote residence: $e\sim p$ means mesh entity $e$ resides
on part $p$.
\[(e \sim p)\equiv(e \sqsubset \bar{P^3_p})\]
Along the same lines, let $R(e)$ denote the resident part set of
a mesh entity, which consist of all parts on which the entity resides.
\[R(e) = \{p|(e\sim p)\}\]
Also let $\downarrow$ denote the one-level downward adjacency of
a mesh entity.
\[\downarrow e = e\{M^{d-1}\}, e \in M^d\]

A fundamental axiom of distributed meshes is this: if a
mesh entity resides on a part, its boundary must also reside
on that part.
\[(e\sim p) \to (\partial e\sim p)\]
The same goes for the downward adjacent entities, since they are contained
in the boundary.
\[\downarrow e \subseteq \partial e,
(e\sim p)\to(\downarrow e\sim p)\]
Therefore, if the downward entities do
not fully reside on a part, the entity cannot reside on that part.
\[\neg (\downarrow e\sim p) \to \neg (e\sim p)\]

Given this, we can define the set of parts on which a mesh entity
is allowed to reside as the intersection of the resident sets of
its downward entities, since these are the parts on which
they all reside.
We can denote this candidate resident set as $R^*(e)$, a superset
of the true resident part set.
\[R(e) \subseteq R^*(e), R^*(e) = \cap_{c\in \downarrow e} R(c)\]

Finally, If the one-level downward adjacent set is known,
the existence and identity of an entity can be confirmed
using upward adjacencies.
Let $\uparrow$ denote the one-level upward adjacent set.
\[\uparrow e = e\{M^{d+1}\}, e \in M^d\]
Given a candidate downward set $(\downarrow e)^*$, we can
find $e$ as follows.
First, if $e$ exists on the same part, it will appear in
the upward sets of all the candidate downward entities.
\[\forall c\in (\downarrow e)^* : (e \in \uparrow c)\]
So, any upward set from a candidate downward entity
gives us a set of candidate entities $\{e\}^*$
to look through.
\[\{e\}^* = \uparrow c, c \in (\downarrow e)^*\]
The candidates can be tested, obviously, by comparing
their downward sets $\downarrow e$ with the candidate
downward set $(\downarrow e)^*$.

\section{Algorithm}

We now have enough proofs to write an algorithm that takes
as input the remote copy links of mesh vertices and
derives the remote copy links for the rest of the mesh.
Remote copy links are required to communicate identities
between parts, and we rightfully assume that having
remote copy information implies having resident part information
about an entity.

For every dimension starting from 1, the algorithm will establish
candidate resident part sets $R^*(e)$ for every entity on a part.
To every candidate part $p \in R^*(e)$ it sends a link proposal
consisting of the downward set $\downarrow e$ on the local part,
which on the remote part becomes a candidate downward set
$(\downarrow e)^*$.
It also sends the local identity of $e$, which
on the remote part becomes $e^*$, and a
remote copy link is made if $e$ is found on
the remote part.
Since all parts will perform this algorithm, it can be seen
that correct links will be established both ways between
copies.
At each dimension, full remote copy information is established
for all entities of that dimension, which is then used to
do the same for the next dimension up.

This algorithm will work correctly even in the case of ghosted
regions and pathological single-element parts,
but it only works for one part per process.
Making it work for multiple parts per process is left as
an exercise for the reader.

\pagebreak

\begin{algorithmic}
\Function{stitch}{$M, R(v)$ for $v \in M^0$}
\State Let $d_\text{max}$ be the highest entity dimension allowed
to have remote copies.
\State Let $p$ be the local part number
\For{$d$ from 1 up to and including $d_\text{max}$}
\For{$e \in M^d$}
\For{$b \in (R^*(e)\setminus p)$}
\State send $(e,\downarrow e)$ to $b$
\EndFor
\EndFor
\For{$(e^*,(\downarrow e)^*)$ received from $a$}
\State choose any $c \in (\downarrow e)^*$
\For{$e \in \uparrow c$}
\If{$\downarrow e = (\downarrow e)^*$}
\State add $(e^*,a)$ as remote copy of $e$
\EndIf
\EndFor
\EndFor
\EndFor
\EndFunction
\end{algorithmic}

\end{document}


\input{sv-algm}

Connected components are widely used in graph analytics as these represents subgraphs in the entire
graph that all vertices are connected. While connected components can not imply the level of
significance of a vertex, having connected components can be useful for community detection,
centrality analytics, and for streaming graph analytics.
Several recent studies show that many real-world social networks may have one connected component
that includes rougly $90\%$ of the vertices \cite{leskovec2009community,strogatz2001exploring}.
While many vertices are part of the large connected component, they are not tighlty bound to this
component and are typically on the ``outskirts'' of this component.

To deal with the increased sizes of graphs numerous parallel algorithms have been designed. One of
the mostly widely used algorithms is that of Shiloach-Vishkin \cite{ShiloachVishkin}. Variations
of Shiloach-Viskin can be found in LIGRA \cite{ligra} for the CPU, Gunrock for the GPU
\cite{gunrock}, and a scalable distributed implementation \cite{flick2015parallel}.
While this algorithm offers a parallel formulation for connected components, it can also be
implemented sequentially or used with a single thread as was done in \cite{greenbranchavoiding} for
figuring out the cost of hardware branch prediction accuracy for graph algorithms.

\subsection*{Shiloach-Vishkin (~\sv) Algorithm for Connected components}

In our current work we augment the ~\sv algorithm to support fault tolerant execution. The ~\sv
algorithm is a label-propagation algorithm where a label of vertex inside the
connected component is propagated to the remaining vertice of that component. Many formulations
use the label of the vertex with either the minimal or maximal id within a component as the value
that is propagate. We to use this formulation and propagate the smallest id within the connected
component. Pseudo code for this algorithm can be found in ~\refAlgorithm{alg:SV_ALG}. The symbols
used in this algorithm and the fault tolerant algorithm introduced in the next section can be found
in \refTable{tab:symbols}.

In the initialization phase, each vertex is placed in its own connected component. From this point
on, in each iteration of the algorithm vertices inspect the connected component value of their
neighbors, \CCVAL. If one of the neighbors has a smaller id then the vertex will switch its
connected component to the one that its neighbor has chosen. \refFigure{fig:svPropagation} depicts
how the label propagates from its initial state, \refFigure{fig:svPropagation} (a), to its final
state \refFigure{fig:svPropagation} (e), where the label of the vertex with the smallest id takes
over all the vertices in the component.  The algorithm terminates when an iteration as completed
and no vertex has swapped its \CCVAL label.
One of the key findings of \cite{greenbranchavoiding} is
that the label swapping occurs at a higher rate in the initial iterations. In the advanced
iteration, the only vertices that have yet to swap their labels are those that are far away from the
vertex with the smallest id.

The time complexity of the $\sv$ algorithm is as follows. Each iteration requires $O(|V|+|E|)$
computations for accessing the connected component array for all vertices and their adadjacencies.
The number of iterations of the algorithm is bound by $O(log(|V|))$ iterations
\cite{ShiloachVishkin} using the shortcutting stage of the algorithm. For many real world networks,
especially small world networks, the number of iterations is bounded by the graph diameter $d$ which
is the upperbound on how long it would take for a value to propagate from one end of the graph to
the other. As such, the total time complexity of the algorithm can be written as $O(log(|V|) \cdot
(|V|+|E|))$ or $O(d \cdot (|V|+|E|))$. We chose the later of these for our analysis.

\subsubsection*{Observartions}

{\bf 1)} The pseudo code in \refAlgorithm{alg:SV_ALG} uses \CCVAL$^i$ to store the
connected components after iteration $i$. While it may seem that these arrays are stored for all
the iterations, in practice it is only necessary to store these for two consecutive
iterations as the previous ones are not necessary.

{\bf 2)} Upon completion of the algorithm, each vertex is assigned to exactly one connected
component and this can be found in \CCVAL$^\infty$. Given that our formulation of \sv uses the
minimal id formulation, we assume that each vertex points to the vertex with the smallest
id in the connected component. We refer to this as the {\bf final and correct state}.

\begin{table*}
\centering
\footnotesize
\caption{Symbols used in the fault free \sv algorithm and in the new fault tolerant algorithm.}
\begin{tabular}[t]{|l|l|r|}\hline
Symbol & Decription & Size\\\hline\hline
$V$ & Vertices in the graph & O(V)\\\hline
$E$ & Edges in the graph & O(E)\\\hline
$adj(v)$ & Adjacency list for vertex $v\in V$ & \\\hline
\CCVAL & Connected component array & O(V)\\\hline
\CCVAL$^i$ & Connected component array after iteration $i$ & O(V)\\\hline
\CCVAL$^\infty$ & The final connected component mapping upon algorithm completion. & O(V)\\\hline

& Fault free \\
\hline
$H$ &  & O(V)\\\hline
\end{tabular}
\label{tab:symbols}
\end{table*}

\begin{figure*}[t]
\centering
	\subfloat[]{\includegraphics[width=0.2\textwidth]{figure/sv1.pdf}}
	\subfloat[]{\includegraphics[width=0.2\textwidth]{figure/sv2.pdf}}
	\subfloat[]{\includegraphics[width=0.2\textwidth]{figure/sv3.pdf}}
	\subfloat[]{\includegraphics[width=0.2\textwidth]{figure/sv4.pdf}}
	\subfloat[]{\includegraphics[width=0.2\textwidth]{figure/sv5.pdf}}

  \caption{These sub-figures conceptually show how the connected component id propagates through
  the graph as time evolves. Subfigures represent snapshots of the algorithm at different times.
For simplicity, this example assumes that all the shown vertices are connected. Initially the
number of connected components is equal to the number vertices. (a) Depicts the initial state in
which each vertex is in its own component. (b)-(d) depict that some vertices belong to the same
connected component yet may require multiple label updates (in either the same iteration or a
separate iteration).
	(e) is the final state in which there is a single connected component.}
  \label{fig:svPropagation}
\end{figure*}


%% !TEX root = manual.tex

\section{Cascade}
\label{sec:tutorial:cascade}

\begin{figure}[h!]
\centering
\includegraphics[width=0.7\textwidth]{figures/tikz/cascade/cascade.png}
\caption{Schematic of cascade with three groups showing hypercube intragroup links and high bandwidth intergroup global links}
\label{fig:topologies:cascade}
\end{figure}

As bandwidth per pin increases, arguments can be made that optimal topologies should be higher radix.
A 3D torus is on the low-radix extreme while a hypercube is a high-radix extreme.
A variation on the dragonfly is the cascade topology implemented by Cray on their Aries interconnects.
A cascade is sometimes viewed as a generalization of flattened butterfly and hypercube topologies with ``virtual'' switches of very high radix,
not dissimilar from the fat-tree implementation with many physical commodity switches composing a single virtual switch.
The cascade topology (Figure \ref{fig:topologies:cascade}) is actually quite simple.
Small groups are connected as a generalized hypercube with full connectivity within a row or column.
Intergroup connections (global links) provide pathways for hopping between groups.
A cascade is usually understood through three parameters:
\begin{itemize}
\item $p$: number of nodes connected to each router
\item $a$: number of routers in a group
\item $h$: number of global links that each switch has
\end{itemize}

For simplicity, only three example global links are show for clarity in the picture.
For the Cray X630, $a = 96$, $h=10$, and $p=4$ so that each router is connected to many other ($h=10$) groups.
The caveat is that in many implementations global links are grouped together for $h=2$ or $3$ fat global links.
These demonstrate well-balanced ratios.
In general, scaling out a cascade should not increase the size of a group, only the number of groups.

\subsection{Allocation and indexing}
\label{subsec:cascade:allocatoin}

The cascade coordinate system is essentially the same as a 3D torus.
The group 2D hypercube layout defines $X$ and $Y$ coordinates.
The group number defines a $Z$ or $G$ coordinate.
Thus the topology in Figure \ref{fig:topologies:cascade} would be specified as

\begin{ViFile}
topology.name = cascade
topology.geometry = 3 3 3
\end{ViFile}
for groups of size $3 \times 3$ with a total of 3 groups.
To complete the specification, the number of global links ($h$) for each router must be given

\begin{ViFile}
topology.group_connections = 10
\end{ViFile}

\subsection{Routing}
\label{subsec:cascade:routing}

It is important to understand the distinction between link bandwidth, channel bandwidth, and pin bandwidth.
All topologies have the same pin bandwidth and channel bandwidth (assuming they use the same technology).
Each router in a topology is constrained to have the same number of channels (called radix, usually about $k=64$).
The number of channels per link changes dramatically from topology to topology.
Low radix topologies like 3D torus can allocate more channels per link,
giving higher bandwidth between adjacent routers.
cascade is higher radix, having many more connections but having lower bandwidth between adjacent routers.
While minimal routing is often sufficient on torus topologies because of the high link bandwidth,
cascade will exhibit very poor performance with minimal routing.
To effectively utilize all the available bandwidth, packets should have a high amount of path diversity.
Packets sent between two routers should take as many different paths as possible to maximize the effective bandwidth point-to-point.

\begin{figure}[h!]
\centering
\includegraphics[width=0.7\textwidth]{figures/tikz/cascade/cascademinroute.png}
\caption{Schematic of cascade showing minimal route. Traveling between groups requires routing to the correct global link, hopping the global link, then routing within a group to the correct final node.}
\label{fig:topologies:cascademinroute}
\end{figure}

Minimal routing itself has a few complications (Figure \ref{fig:topologies:cascademinroute}).
Each router only has a few global links.
Thus, traveling from e.g. the blue router at X=3,Y=2,G=0 to the red router at X=1,Y=2,G=2, there is no direct link between the routers.
Furthermore, there is no direct link between Groups 0 and 2.
Thus packets must route through the purple intermediate nodes.
First, the packet hops to X=3,Y=3, G=0.
This router has a global link to Group 2, allowing the packet to hop to the next intermediate router at X=1, Y=3, G=2.
Finally, the minimal route completes by hopping within Group 2 to the final destination.

\begin{figure}[h!]
\centering
\includegraphics[width=0.7\textwidth]{figures/tikz/cascade/cascadevaliant.png}
\caption{Schematic of cascade showing Valiant route. Traveling between groups requires routing to a random intermediate node, then routing minimally to the final destination.}
\label{fig:topologies:cascadevaliantroute}
\end{figure}

To improve on minimal routing, global routing strategies are required (global routing is distinguished here from adaptive routing).
Global essentially means ``not minimal'' and spreads packets along many different paths.
The simplest global routing strategy is Valiant routing, which falls in the global, oblivious category (Figure \ref{fig:topologies:dflyvaliantroute}).
Oblivious simply means packets are scattered randomly without measuring congestion.
In Valiant routing, each packet does the following:
\begin{itemize}
\item Pick a random intermediate node
\item Route minimally to random node
\item Route minimally from random node to destination node
\end{itemize}
This is somewhat counterintuitive at first.
Rather than go directly to the destination node, packets go out of their way to a random node, shown in Figure \ref{fig:topologies:dflyvaliantroute} as the yellow router.
Thus, routing from the blue router in Group 0 to the red router in Group 2 first follows the minimal path (green routers) to the randomly selected yellow router in Group 1.
From there, a second minimal path is taken through the orange routers to the final destination.
In cases with high congestion or even for large messages on a quiet network, this actually improves performance.
If a point-to-point message is composed of ten packets,
all ten packets will follow different paths to the final destination.
This essentially multiplies the maximum bandwidth by a factor of ten.
Valiant routing can be specified as

\begin{ViFile}
router = valiant
\end{ViFile}

In contrast, UGAL routing is a global, adaptive strategy, making decisions based on congestion.
Because Valiant is oblivious, it often sends too many packets to far away random nodes.
Following a Valiant path is only relevant when enough packets fill up router queues, creating congestion.
UGAL does the following steps:
\begin{itemize}
\item Start routing minimally
\item On each step, check congestion (buffer queue depth)
\item If congestion is too heavy, switch to Valiant and re-route to random intermediate node. Otherwise stay on minimal path.
\end{itemize}
UGAL packets stay on a minimal path until congestion forces them to use a Valiant strategy.
This routing can be specified as:

\begin{ViFile}
router = ugal
\end{ViFile}


%!TEX root = ./Basilisk-SPACECRAFTPLUS-20170808.tex

\section{Test Description and Success Criteria}
This test is located in \texttt{simulation/dynamics/spacecraftPlus/\_UnitTest/\newline
test\_spacecraftPlus.py}. Depending on the scenario, there are different success criteria. These are outlined in the following subsections:
\subsection{Translation Only with Gravity Scenario}
In this test the simulation is placed into orbit around Earth with point gravity and the spacecraft only has translational equations being evaluated. The following parameters are being tested.
\begin{itemize}
	\item Conservation of orbital angular momentum
	\item Conservation of orbital energy
	\item Achieving the expected final position
\end{itemize}

\subsection{Rotational Only Scenario}
In this test, the spacecraft only has rotational equations being evaluated. The following parameters describe the success criteria.
\begin{itemize}
\item Conservation of rotational angular momentum
\item Conservation of rotational energy
\item Achieving the expected final attitude
\item Switching of MRPs check
\item Agreement with BOE calculation for rotational dynamics
\end{itemize}
The calculations for both the switching of the MRPs and the BOE for rotational dynamics need to be further discussed. The following sections outline these checks.

\subsubsection{MRP switching test}
The MRP switching check needs to be discussed. In Basilisk the MRPs are switched to the shadow set in \textit{hubEffector} after one step of the integration using the method \textit{modifyStates()} which is available to all \textit{stateEffectors} that need to change their states to a different but equivalent form. The MRP switching adheres to the following equation\cite{schaub}:

\begin{equation}
\begin{gathered}
\begin{aligned}
&\textnormal{\textbf{if}}\quad [s = \vert \bm \sigma(t + \D t) \vert ] > 1  \quad \textnormal{\textbf{then}}\\
&\quad \bm \sigma(t + \D t) = - \frac{\bm \sigma(t + \D t)}{s^2}\\
&\textnormal{\textbf{end if}}
\end{aligned}
\end{gathered}
\label{eq:ballin}
\end{equation}

To check that the switch in the simulation is behaving the way it should, the following check was developed. If the switch happened at time $t_\textnormal{s}$, then there are two variables from the sim that will be used: $\bm \sigma(t_\textnormal{s-1})$ and $\bm \sigma(t_\textnormal{s})$. The intermediate MRP that is switched in the sim is not an output of the simulation, but we will call this variable $\bm \sigma_0(t_\textnormal{s})$. To check the switching the following math occurs:

\begin{equation}
\bm \sigma_0(t_\textnormal{s}) \approx \bm \sigma(t_\textnormal{s-1}) + \frac{\bm \sigma(t_\textnormal{s-1}) - \bm \sigma(t_\textnormal{s-2})}{\Delta t} \Delta t
\end{equation}
Where this is an Euler approximation to the intermediate MRP before the switch occurs. Now using Eq.~\eqref{eq:ballin} the following definition is made:

\begin{equation}
\bm \sigma_{\textnormal{ch}}(t_\textnormal{s}) = - \frac{\bm \sigma_0(t_\textnormal{s})}{\vert \bm \sigma_0(t_\textnormal{s}) \vert^2}
\end{equation}
Where $\bm \sigma_{\textnormal{ch}}(t_\textnormal{s})$ is the MRP to check vs. the simulation MRP. Therefore, in the integrated test, the test is making sure that $ \bm \sigma(t_\textnormal{s}) \approx \bm \sigma_{\textnormal{ch}}(t_\textnormal{s})$

\subsubsection{Rotational Dynamics BOE description}

To validate the rotational dynamics, a relationship that involves both the attitude and attitude rate was chosen. The following back of the envelope calculation is taken from\cite{schaub} and repeated here for convenience. The angular momentum vector is chosen to be aligned with the inertial frame:

\begin{equation}
\leftexp{\cal{N}}{\bm H} = -H \hat{\bm n}_3 = \leftexp{\cal{N}}{\begin{bmatrix}
	0\\
	0\\
	-H
	\end{bmatrix}}
\end{equation}
The following relationship is written:

\begin{equation}
\leftexp{\cal{B}}{\bm H} = [BN] \leftexp{\cal{N}}{\bm H}
\end{equation}
Since MRPs are the attitude parameterization chosen for Basilisk, then the direction cosine matrix $[BN]$ is written in terms of the current MRPs. If there are no external torque's acting on the spacecraft, then the angular momentum vector will be conserved in the inertial frame. Therefore, using the definition of transformation from MRPs to the direction cosine matrix\cite{schaub}, the following relationship will always hold:

\begin{equation}
\leftexp{\cal{B}}{\begin{bmatrix}
	H_1\\
	H_2\\
	H_3
	\end{bmatrix}} = -H\leftexp{\cal{B}}{\begin{bmatrix}
	8 \sigma_1 \sigma_3 - 4 \sigma_2 (1 - \sigma^2)\\
	8 \sigma_2 \sigma_3 + 4 \sigma_1 (1 - \sigma^2)\\
	4 (-\sigma_1^2 - \sigma_2^2 + \sigma_3^2) + (1 - \sigma^2)^2
	\end{bmatrix}} = \leftexp{\cal{B}}{\begin{bmatrix}
	I_1 \omega_1\\
	I_2 \omega_2\\
	I_3 \omega_3
	\end{bmatrix}}
\end{equation}
Finally, the current angular velocity components in the body frame can be found from the current MRPs using the following relationship:

\begin{equation}
\omega_1 = -\frac{H}{I_1} \Big[8 \sigma_1 \sigma_3 - 4 \sigma_2 (1 - \sigma^2)\Big]
\end{equation}

\begin{equation}
\omega_2 = -\frac{H}{I_2} \Big[8 \sigma_2 \sigma_3 + 4 \sigma_1 (1 - \sigma^2)\Big]
\end{equation}

\begin{equation}
\omega_3 = -\frac{H}{I_3} \Big[4 (-\sigma_1^2 - \sigma_2^2 + \sigma_3^2) + (1 - \sigma^2)^2\Big]
\end{equation}
This gives a closed from solution between the current MRPs and the angular velocity of the spacecraft. The test picks 5 points during a simulation and verifies that this relationship holds true.

\subsection{Translational and Rotational Scenario}
In this test, the spacecraft is placed into an orbit with simple gravity and also has rotational states associated with the spacecraft. The following parameters describe the success criteria.
\begin{itemize}
	\item Conservation of orbital angular momentum
	\item Conservation of orbital energy
	\item Achieving the expected final position (same as translational only test)
	\item Conservation of rotational angular momentum
	\item Conservation of rotational energy
	\item Achieving the expected final attitude (same as rotational only test)
\end{itemize}

\subsection{Translational BOE Calculation Scenario}

The translational BOE calculation can be seen in Figure~\ref{fig:BOETrans}. In this test a positive force is placed on the hub in the $\hat{\bm b}_1$ direction with no torque and no initial rotation of the spacecraft. This results in the 1 degree of freedom problem seen in Figure~\ref{fig:BOETrans}. The force is applied for some length of time, left off for a length of time, and then a negative force is applied ot the system for some length of time. The test is ensuring that Basilisk is giving the same results as the BOE calculation.

\begin{figure}[htbp]
	\centerline{
		\includegraphics[width=0.8\textwidth]{Figures/TranslationBOE}}
	\caption{Simple Translation BOE Calculation}
	\label{fig:BOETrans}
\end{figure}

\clearpage

\subsection{Dynamics Calculated About Point B Test}

The dynamics for the spacecraft have been derived in relation to the body frame origin, point $B$, which is not necessarily coincident with point $C$. Therefore the dynamicEffectors and stateEffectors define their torques about point $B$ as oppose to about point $C$. This allows the simulation to have multi-body dynamics where the center of mass of the spacecraft can move with respect to the body frame. However, in rigid body dynamics it is very common to have the body frame origin coincident with the center of mass of the spacecraft. Therefore, to confirm that the dynamics has been developed correctly to handle this torque mapping a test has been created.

The test runs two simulations: one with the body frame origin defined at the center of mass of the spacecraft, and one with the body frame origin not coincident with the center of mass. An external force and corresponding torque is applied to the spacecraft in both cases: in the first case the torque is being defined about point $B=C$, and in the second case the torque is being defined about point $B$. Both simulations are given identical initial conditions and the expectation is that the simulations should give identical results. The following parameters describe the success criteria.
\begin{itemize}
	\item Agreement between both simulations for the translational states
	\item Agreement between both simulations for the attitude states
\end{itemize}

\section{Test Parameters}

Since this is an integrated test, the inputs to the test are the physical parameters of the spacecraft along with the initial conditions of the states. These parameters are outlined in Tables~\ref{tab:hub}-~\ref{tab:initial}. Additionally, the error tolerances can be seen in Table~\ref{tab:errortol}.

The energy/momentum conservation, rotational BOE, and translational BOE relative tolerance values were chosen to be 1e-10 to ensure cross-platform success. However, the expected relative tolerance for these three tests are $\approx$ 1e-15, which is about machine precision. This is because the integration time step was low enough that the integrator was introducing very small errors with respect to the exact solution. This gives great confidence in the simulations. The position and attitude relative tolerance values (including Point B Vs. Point C tests) were chosen because the values saved in python to compare to had 10 significant digits. Therefore, 1e-8 was chosen to ensure platform success. This agreement is very good and gives further confidence in the solution. Finally, the MRP switching relative tolerance was chosen to be 1e-5 because of the time step dependency of this test. Since the test involves a numerical difference the accuracy gets better the smaller the step size. For example with a step size of 0.001, the resulting relative accuracy was 1e-7 but if a step size of 0.001 is used, 1e-13 was the resulting relative accuracy. Therefore, 1e-5 was chosen to ensure cross platform success and to use a step size of 0.001 for speed. However, since as the step size goes down the simulation approaches the analytical solution, this tests gives very good confidence in the simulation.

\begin{table}[htbp]
	\caption{Spacecraft Hub Parameters}
	\label{tab:hub}
	\centering \fontsize{10}{10}\selectfont
	\begin{tabular}{ c | c | c | c } % Column formatting,
		\hline
		\textbf{Name}  & \textbf{Description}  & \textbf{Value} & \textbf{Units} \\
		\hline
		mHub  & mass & 100.0 & kg \\
		IHubPntBc\_B & Inertia in $\cal{B}$ frame & $\begin{bmatrix}
		500.0 & 0.0 & 0.0\\
		0.0 & 200.0 & 0.0\\
		0.0 & 0.0 & 300.0
		\end{bmatrix}$ & kg-m$^2$ \\
		r\_BcB\_B & CoM Location in $\cal{B}$ frame & $\begin{bmatrix}
		0.0 & 0.0 & 0.0 \end{bmatrix}^T$ & m \\
		\hline
	\end{tabular}
\end{table}

\begin{table}[htbp]
	\caption{Initial Conditions of the simulations}
	\label{tab:initial}
	\centering \fontsize{10}{10}\selectfont
	\begin{tabular}{ c | p{2.25in} | c | c } % Column formatting,
		\hline
		\textbf{Name}  & \textbf{Description}  & \textbf{Value} & \textbf{Units} \\
		\hline
		r\_CN\_NInit & Initial Position of S/C (gravity scenarios) & $\begin{bmatrix}
		-4020339 &	7490567 & 5248299
		\end{bmatrix}^T$ & m \\
		v\_CN\_NInit & Initial Velocity of S/C (gravity scenarios) & $\begin{bmatrix}
		-5199.78 & -3436.68 & 1041.58
		\end{bmatrix}^T$ & m/s \\
		r\_CN\_NInit & Initial Position of S/C (no gravity) & $\begin{bmatrix}
		0.0 & 0.0 & 0.0
		\end{bmatrix}^T$ & m \\
		v\_CN\_NInit & Initial Velocity of S/C (no gravity) & $\begin{bmatrix}
		0.0 & 0.0 & 0.0
		\end{bmatrix}^T$ & m/s \\
		sigma\_BNInit & Initial MRP of $\cal{B}$ frame (All Except Rotation Only) & $\begin{bmatrix}
		0.0 & 0.0 & 0.0
		\end{bmatrix}^T$ & - \\
		sigma\_BNInit & Initial MRP of $\cal{B}$ frame (Rotation Only) & $\begin{bmatrix}
		0.09734 & 0.62362 & 0.04679
		\end{bmatrix}^T$ & - \\
		omega\_BN\_BInit & Initial Angular Velocity (All Except Translation BOE) & $\begin{bmatrix}
		0.5 & -0.4 & 0.7
		\end{bmatrix}^T$ & rad/s \\
		omega\_BN\_BInit & Initial Angular Velocity (Translation BOE) & $\begin{bmatrix}
		0.0 & 0.0 & 0.0
		\end{bmatrix}^T$ & rad/s \\
		\hline
	\end{tabular}
\end{table}

\begin{table}[htbp]
	\caption{Error Tolerance - Note: Relative Tolerance is $\textnormal{abs}(\frac{\textnormal{truth} - \textnormal{value}}{\textnormal{truth}}$)}
	\label{tab:errortol}
	\centering \fontsize{10}{10}\selectfont
	\begin{tabular}{ c | c } % Column formatting,
		\hline
		\textbf{Test}   & \textbf{Relative Tolerance} \\
		\hline
		Energy and Momentum Conservation & 1e-10 \\
		Position Check & 1e-8 \\
		Attitude Check & 1e-8 \\
		MRP Switching Check & 1e-5 \\
		Rotational BOE & 1e-10 \\
		Translational BOE & 1e-10 \\
		Point B Vs. Point C & 1e-8 \\
		\hline
	\end{tabular}
\end{table}

\clearpage

\section{Test Results}

\subsection{Translation Only with Gravity Scenario}
\begin{figure}[htbp]
	\centerline{
		\includegraphics[width=0.8\textwidth]{../AutoTeX/scPlusChangeInOrbitalEnergyTranslationOnly}}
	\caption{Change in Orbital Energy Translation Only}
	\label{fig:ChangeInOrbitalEnergyTranslationOnly}
\end{figure}
\begin{figure}[htbp]
	\centerline{
		\includegraphics[width=0.8\textwidth]{../AutoTeX/scPlusChangeInOrbitalAngularMomentumTranslationOnly}}
	\caption{Change in Orbital Angular Momentum Translation Only}
	\label{fig:ChangeInOrbitalAngularMomentumTranslationOnly}
\end{figure}
\clearpage

\subsection{Rotational Only Scenario}
\begin{figure}[htbp]
	\centerline{
		\includegraphics[width=0.8\textwidth]{../AutoTeX/scPlusChangeInRotationalEnergyRotationOnly}}
	\caption{Change in Rotational Energy Rotation Only}
	\label{fig:ChangeInRotationalEnergyRotationOnly}
\end{figure}
\begin{figure}[htbp]
	\centerline{
		\includegraphics[width=0.8\textwidth]{../AutoTeX/scPlusChangeInRotationalAngularMomentumRotationOnly}}
	\caption{Change in Rotational Angular Momentum Rotation Only}
	\label{fig:ChangeInRotationalAngularMomentumRotationOnly}
\end{figure}
\begin{figure}[htbp]
	\centerline{
		\includegraphics[width=0.8\textwidth]{../AutoTeX/scPlusMRPs}}
	\caption{Attitude of Spacecraft in MRPs}
	\label{fig:MRPs}
\end{figure}
\begin{figure}[htbp]
	\centerline{
		\includegraphics[width=0.8\textwidth]{../AutoTeX/scPlusMRPSwitching}}
	\caption{MRP Switching}
	\label{fig:MRPSwitching}
\end{figure}
\begin{figure}[htbp]
	\centerline{
		\includegraphics[width=0.8\textwidth]{../AutoTeX/scPlusBasiliskVsBOECalcForRotation}}
	\caption{Basilisk Vs BOE Calc For Rotation}
	\label{fig:BasiliskVsBOECalcForRotation}
\end{figure}
\clearpage

\subsection{Translational and Rotational Scenario}
\begin{figure}[htbp]
	\centerline{
		\includegraphics[width=0.8\textwidth]{../AutoTeX/scPlusChangeInOrbitalEnergyTranslationAndRotation}}
	\caption{Change in Orbital Energy Translation And Rotation}
	\label{fig:ChangeInOrbitalEnergyTranslationAndRotation}
\end{figure}
\begin{figure}[htbp]
	\centerline{
		\includegraphics[width=0.8\textwidth]{../AutoTeX/scPlusChangeInOrbitalAngularMomentumTranslationAndRotation}}
	\caption{Change in Orbital Angular Momentum Translation And Rotation}
	\label{fig:ChangeInOrbitalAngularMomentumTranslationAndRotation}
\end{figure}
\begin{figure}[htbp]
	\centerline{
		\includegraphics[width=0.8\textwidth]{../AutoTeX/scPlusChangeInRotationalEnergyTranslationAndRotation}}
	\caption{Change in Rotational Energy Translation And Rotation}
	\label{fig:ChangeInRotationalEnergyTranslationAndRotation}
\end{figure}
\begin{figure}[htbp]
	\centerline{
		\includegraphics[width=0.8\textwidth]{../AutoTeX/scPlusChangeInRotationalAngularMomentumTranslationAndRotation}}
	\caption{Change in Rotational Angular Momentum Translation And Rotation}
	\label{fig:ChangeInRotationalAngularMomentumTranslationAndRotation}
\end{figure}
\clearpage

\subsection{Translational BOE Calculation Scenario}
\begin{figure}[htbp]
	\centerline{
		\includegraphics[width=0.8\textwidth]{../AutoTeX/scPlusTranslationPositionBOE}}
	\caption{Translation Position BOE}
	\label{fig:TranslationPositionBOE}
\end{figure}
\begin{figure}[htbp]
	\centerline{
		\includegraphics[width=0.8\textwidth]{../AutoTeX/scPlusTranslationVelocityBOE}}
	\caption{Translation Velocity BOE}
	\label{fig:TranslationVelocityBOE}
\end{figure}
\clearpage

\subsection{Dynamics Calculated About Point B Test}
\begin{figure}[htbp]
	\centerline{
		\includegraphics[width=0.8\textwidth]{../AutoTeX/scPlusPointBVsPointCTranslation}}
	\caption{PointB Vs PointC Translation}
	\label{fig:PointBVsPointCTranslation}
\end{figure}
\begin{figure}[htbp]
	\centerline{
		\includegraphics[width=0.8\textwidth]{../AutoTeX/scPlusPointBVsPointCAttitude}}
	\caption{PointB Vs PointC Attitude}
	\label{fig:PointBVsPointCAttitude}
\end{figure}
\clearpage


\hypertarget{classnumpp_1_1matrix_1_1sparse_1_1nested}{}\section{numpp\+:\+:matrix\+:\+:sparse\+:\+:nested$<$ T, Rows, Columns $>$ Class Template Reference}
\label{classnumpp_1_1matrix_1_1sparse_1_1nested}\index{numpp\+::matrix\+::sparse\+::nested$<$ T, Rows, Columns $>$@{numpp\+::matrix\+::sparse\+::nested$<$ T, Rows, Columns $>$}}

Block nested version of sparse matrix.

{\ttfamily \#include $<$sparse\+\_\+block\+\_\+nested.\+hpp$>$}

\subsection*{Public Types}
\begin{DoxyCompactItemize}
\item
\mbox{\Hypertarget{classnumpp_1_1matrix_1_1sparse_1_1nested_a7ee7220e8a4fb147645e5e041d5e5bec}\label{classnumpp_1_1matrix_1_1sparse_1_1nested_a7ee7220e8a4fb147645e5e041d5e5bec}}
using {\bfseries value\+\_\+type} = T
\item
\mbox{\Hypertarget{classnumpp_1_1matrix_1_1sparse_1_1nested_ae6ff817777e93a23739de12daaff86ca}\label{classnumpp_1_1matrix_1_1sparse_1_1nested_ae6ff817777e93a23739de12daaff86ca}}
using {\bfseries size\+\_\+type} = std\+::size\+\_\+t
\item
\mbox{\Hypertarget{classnumpp_1_1matrix_1_1sparse_1_1nested_ad9b24c32e0151135d3bf17a17109dc36}\label{classnumpp_1_1matrix_1_1sparse_1_1nested_ad9b24c32e0151135d3bf17a17109dc36}}
using {\bfseries reference} = T \&
\item
\mbox{\Hypertarget{classnumpp_1_1matrix_1_1sparse_1_1nested_a1d0a0d4ab6c821ba46b43c4b96358da3}\label{classnumpp_1_1matrix_1_1sparse_1_1nested_a1d0a0d4ab6c821ba46b43c4b96358da3}}
using {\bfseries const\+\_\+reference} = const T \&
\item
\mbox{\Hypertarget{classnumpp_1_1matrix_1_1sparse_1_1nested_ad93736ab4b7e04a671a5c2a1606129ee}\label{classnumpp_1_1matrix_1_1sparse_1_1nested_ad93736ab4b7e04a671a5c2a1606129ee}}
using {\bfseries pointer} = T $\ast$
\item
\mbox{\Hypertarget{classnumpp_1_1matrix_1_1sparse_1_1nested_aa940950e23a925cc7deb8911ec803f47}\label{classnumpp_1_1matrix_1_1sparse_1_1nested_aa940950e23a925cc7deb8911ec803f47}}
using {\bfseries const\+\_\+pointer} = const T $\ast$
\end{DoxyCompactItemize}
\subsection*{Public Member Functions}
\begin{DoxyCompactItemize}
\item
\mbox{\Hypertarget{classnumpp_1_1matrix_1_1sparse_1_1nested_a7b64faee8e6532d8fd535fc069e75612}\label{classnumpp_1_1matrix_1_1sparse_1_1nested_a7b64faee8e6532d8fd535fc069e75612}}
{\bfseries nested} (const \hyperlink{classnumpp_1_1matrix_1_1sparse_1_1nested}{nested} \&)=default
\item
\mbox{\Hypertarget{classnumpp_1_1matrix_1_1sparse_1_1nested_ae2635e88208229453ffa0ca7858801f8}\label{classnumpp_1_1matrix_1_1sparse_1_1nested_ae2635e88208229453ffa0ca7858801f8}}
{\bfseries nested} (\hyperlink{classnumpp_1_1matrix_1_1sparse_1_1nested}{nested} \&\&)=default
\item
\mbox{\Hypertarget{classnumpp_1_1matrix_1_1sparse_1_1nested_acb521971efcd22e628a97c398c9af9ee}\label{classnumpp_1_1matrix_1_1sparse_1_1nested_acb521971efcd22e628a97c398c9af9ee}}
\hyperlink{classnumpp_1_1matrix_1_1sparse_1_1nested}{nested} \& {\bfseries operator=} (\hyperlink{classnumpp_1_1matrix_1_1sparse_1_1nested}{nested} \&\&)=default
\item
\mbox{\Hypertarget{classnumpp_1_1matrix_1_1sparse_1_1nested_aefc9f1be3eb621a4a287f313fef69f08}\label{classnumpp_1_1matrix_1_1sparse_1_1nested_aefc9f1be3eb621a4a287f313fef69f08}}
\hyperlink{classnumpp_1_1matrix_1_1sparse_1_1nested}{nested} \& {\bfseries operator=} (const \hyperlink{classnumpp_1_1matrix_1_1sparse_1_1nested}{nested} \&)=default
\item
\mbox{\Hypertarget{classnumpp_1_1matrix_1_1sparse_1_1nested_ad5277725c13cb3677aab4f3bedbe8601}\label{classnumpp_1_1matrix_1_1sparse_1_1nested_ad5277725c13cb3677aab4f3bedbe8601}}
{\bfseries nested} (std\+::initializer\+\_\+list$<$ std\+::initializer\+\_\+list$<$ T $>$$>$ elements)
\item
\mbox{\Hypertarget{classnumpp_1_1matrix_1_1sparse_1_1nested_ad9af43e4278ec50a869996a3b56a7ad1}\label{classnumpp_1_1matrix_1_1sparse_1_1nested_ad9af43e4278ec50a869996a3b56a7ad1}}
size\+\_\+type {\bfseries size} () const noexcept
\item
const std\+::array$<$ std\+::vector$<$ \hyperlink{structnumpp_1_1matrix_1_1sparse_1_1impl_1_1inner__block}{impl\+::inner\+\_\+block}$<$ T $>$ $>$, Rows $>$ \& \hyperlink{classnumpp_1_1matrix_1_1sparse_1_1nested_a56a31c654f21e001e6e4cc4aa7055ee1}{data} () const noexcept
\item
std\+::array$<$ std\+::vector$<$ \hyperlink{structnumpp_1_1matrix_1_1sparse_1_1impl_1_1inner__block}{impl\+::inner\+\_\+block}$<$ T $>$ $>$, Rows $>$ \& \hyperlink{classnumpp_1_1matrix_1_1sparse_1_1nested_a1201f9550dded2b187221ccf768a88f3}{data} () noexcept
\item
{\footnotesize template$<$typename U $>$ }\\auto \hyperlink{classnumpp_1_1matrix_1_1sparse_1_1nested_a5348b9ed5e038a10885b5b849614fdba}{operator$\ast$} (const \hyperlink{classnumpp_1_1vector}{numpp\+::vector}$<$ U, Columns, false $>$ \&vec)
\end{DoxyCompactItemize}

\subsection{Detailed Description}
\subsubsection*{template$<$typename T, std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$\newline
class numpp\+::matrix\+::sparse\+::nested$<$ T, Rows, Columns $>$}

Block nested version of sparse matrix.

\begin{DoxyTemplParams}{Template Parameters}
{\em T} & arithmetic type contained in matrix class \\
\hline
{\em Rows} & number of rows in matrix \\
\hline
{\em Columns} & number of columns in matrix\\
\hline
\end{DoxyTemplParams}
{\bfseries This implementation is an experiment in cache hit-\/rate.~\newline
 } Whole sparse matrix is contained in one array, inside there is a nested block which contains each data block After each block operation calculating row is performed.

\begin{DoxyWarning}{Warning}
{\bfseries For parallelization of the sparse matrix dense vector multiplication you need compiler with Open\+MP support}

Only sparse matrix dense vector multiplication implemented

{\bfseries Each row has to be seperate std\+::initializer\+\_\+list}
\end{DoxyWarning}
{\bfseries Pros\+:}
\begin{DoxyItemize}
\item Even smaller memory overhead than \hyperlink{classnumpp_1_1matrix_1_1sparse_1_1block}{numpp\+::matrix\+::sparse\+::block} (one less element per block kept in memory)
\item Higher possibility of S\+I\+MD optimization than above
\end{DoxyItemize}

{\bfseries Cons\+:}
\begin{DoxyItemize}
\item Additional operations of read for every block
\item Cache locality may be worse as two vectors are nested inside each other
\end{DoxyItemize}

{\bfseries Example\+:}
\begin{DoxyCode}
\hyperlink{classnumpp_1_1matrix_1_1sparse_1_1nested}{numpp::matrix::sparse::nested<double, 3,3>} mat\{\{0,  0,   1\},
                                                \{0,  2.3, 0\},
                                                \{0,  0,   13.7\}
                                               \};
constexpr numpp::matrix::vector<double, 3> vec\{1,2,3\};
\textcolor{keyword}{auto} result = mat*vec;
\end{DoxyCode}

\begin{DoxyCode}
\textcolor{preprocessor}{#include"numpp/structures/matrices/sparse.hpp"}
\end{DoxyCode}

\subsection{Member Function Documentation}
\mbox{\Hypertarget{classnumpp_1_1matrix_1_1sparse_1_1nested_a56a31c654f21e001e6e4cc4aa7055ee1}\label{classnumpp_1_1matrix_1_1sparse_1_1nested_a56a31c654f21e001e6e4cc4aa7055ee1}}
\index{numpp\+::matrix\+::sparse\+::nested@{numpp\+::matrix\+::sparse\+::nested}!data@{data}}
\index{data@{data}!numpp\+::matrix\+::sparse\+::nested@{numpp\+::matrix\+::sparse\+::nested}}
\subsubsection{\texorpdfstring{data()}{data()}\hspace{0.1cm}{\footnotesize\ttfamily [1/2]}}
{\footnotesize\ttfamily template$<$typename T , std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ \\
const std\+::array$<$std\+::vector$<$\hyperlink{structnumpp_1_1matrix_1_1sparse_1_1impl_1_1inner__block}{impl\+::inner\+\_\+block}$<$T$>$ $>$, Rows$>$\& \hyperlink{classnumpp_1_1matrix_1_1sparse_1_1nested}{numpp\+::matrix\+::sparse\+::nested}$<$ T, Rows, Columns $>$\+::data (\begin{DoxyParamCaption}{ }\end{DoxyParamCaption}) const\hspace{0.3cm}{\ttfamily [inline]}, {\ttfamily [noexcept]}}

Returns underlying data structure \mbox{\Hypertarget{classnumpp_1_1matrix_1_1sparse_1_1nested_a1201f9550dded2b187221ccf768a88f3}\label{classnumpp_1_1matrix_1_1sparse_1_1nested_a1201f9550dded2b187221ccf768a88f3}}
\index{numpp\+::matrix\+::sparse\+::nested@{numpp\+::matrix\+::sparse\+::nested}!data@{data}}
\index{data@{data}!numpp\+::matrix\+::sparse\+::nested@{numpp\+::matrix\+::sparse\+::nested}}
\subsubsection{\texorpdfstring{data()}{data()}\hspace{0.1cm}{\footnotesize\ttfamily [2/2]}}
{\footnotesize\ttfamily template$<$typename T , std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ \\
std\+::array$<$std\+::vector$<$\hyperlink{structnumpp_1_1matrix_1_1sparse_1_1impl_1_1inner__block}{impl\+::inner\+\_\+block}$<$T$>$ $>$, Rows$>$\& \hyperlink{classnumpp_1_1matrix_1_1sparse_1_1nested}{numpp\+::matrix\+::sparse\+::nested}$<$ T, Rows, Columns $>$\+::data (\begin{DoxyParamCaption}{ }\end{DoxyParamCaption})\hspace{0.3cm}{\ttfamily [inline]}, {\ttfamily [noexcept]}}

Returns underlying data structure \mbox{\Hypertarget{classnumpp_1_1matrix_1_1sparse_1_1nested_a5348b9ed5e038a10885b5b849614fdba}\label{classnumpp_1_1matrix_1_1sparse_1_1nested_a5348b9ed5e038a10885b5b849614fdba}}
\index{numpp\+::matrix\+::sparse\+::nested@{numpp\+::matrix\+::sparse\+::nested}!operator$\ast$@{operator$\ast$}}
\index{operator$\ast$@{operator$\ast$}!numpp\+::matrix\+::sparse\+::nested@{numpp\+::matrix\+::sparse\+::nested}}
\subsubsection{\texorpdfstring{operator$\ast$()}{operator*()}}
{\footnotesize\ttfamily template$<$typename T , std\+::size\+\_\+t Rows, std\+::size\+\_\+t Columns$>$ \\
template$<$typename U $>$ \\
auto \hyperlink{classnumpp_1_1matrix_1_1sparse_1_1nested}{numpp\+::matrix\+::sparse\+::nested}$<$ T, Rows, Columns $>$\+::operator$\ast$ (\begin{DoxyParamCaption}\item[{const \hyperlink{classnumpp_1_1vector}{numpp\+::vector}$<$ U, Columns, false $>$ \&}]{vec }\end{DoxyParamCaption})\hspace{0.3cm}{\ttfamily [inline]}}

Function multiplying sparse matrix and dense vector

\begin{DoxyParams}{Parameters}
{\em vec} & Vector which will be multiplied \\
\hline
\end{DoxyParams}
\begin{DoxyReturn}{Returns}
vector$<$\+U, Rows, false$>$
\end{DoxyReturn}

The documentation for this class was generated from the following file\+:\begin{DoxyCompactItemize}
\item
structures/matrices/sparse/sparse\+\_\+block\+\_\+nested.\+hpp\end{DoxyCompactItemize}