\documentclass{article}
\usepackage{amsmath}
\newcommand{\ct}{\texttt}
\newcommand{\luint}{\ct{lu\_int}}
\newcommand{\double}{\ct{double}}

% page size
\setlength{\hoffset}{-1in}
\setlength{\voffset}{-1in}
\setlength{\oddsidemargin}{3.5cm}
\setlength{\evensidemargin}{3.5cm}
\setlength{\topmargin}{2cm}
\setlength{\textwidth}{14cm}
\setlength{\textheight}{22cm}

\title{BASICLU User Guide}
\author{Version 2.2}

\begin{document}
\maketitle

%\setcounter{tocdepth}{1}
\tableofcontents
\newpage

%-------------------------------------------------------------------------------
\section{Algorithm}
%-------------------------------------------------------------------------------
BASICLU implements a right-looking $LU$ factorization with dynamic Markowitz
search and columnwise threshold pivoting. After a column modification to the
matrix it applies either a permutation or the Forrest-Tomlin update to maintain
a factorized form. It uses the method of Gilbert and Peierls to solve triangular
systems with a sparse right-hand side. A more detailed explanation of the method
is given in [Technical Report ERGO 17-002,
http://www.maths.ed.ac.uk/ERGO/preprints.html].

%-------------------------------------------------------------------------------
\section{Installation}
\label{sec:install}
%-------------------------------------------------------------------------------
\subsection{Compiling BASICLU}
Compiling BASICLU requires GNUmake and a C compiler that (partly) supports the
ANSI C99 standard.

To compile the package type \ct{make} in the BASICLU directory. This will create
a static and a shared library inside \ct{lib/}. It will also compile a
standalone program \ct{maxvolume} in \ct{example/}. You can call the latter with
the matrices in \ct{example/data/}.

Compiler and linker flags can be changed in \ct{config.mk} or can be given to
\ct{make} on the command line. See the documentation in \ct{config.mk}.

\subsection{The integer type}
BASICLU integer variables are of type \luint, which is \ct{typedef}'ed in
\ct{basiclu.h}. \luint\ must be a signed integer type. The default is
\ct{int64\_t}. It can be changed before compiling the package. Note:
\begin{itemize}
\item The BASICLU routines do not check for integer overflow. It is in your
  responsibility to choose a sufficiently large integer type for your problems.
\item It is required that all integer values arising in the computation can be
  stored in \double\ variables and converted back to \luint\ without altering
  their value.
\end{itemize}

%-------------------------------------------------------------------------------
\section{Low level C interface}
%-------------------------------------------------------------------------------
The low level C interface consists of routines which do not allocate memory.
Memory must be provided by the user and reallocated on request. To use the low
level C interface, user code must include \ct{basiclu.h}. Defined constants
start with \ct{BASICLU\_} and function names start with \ct{basiclu\_}.

Memory must be provided in form of four \luint\ arrays and four \double\ arrays:
\begin{description}
\item{\ct{istore}, \ct{xstore}} are arrays whose size depends only on the matrix
  dimension (see \ct{basiclu\_initialize} for their required length).
  \ct{xstore} is used to input parameters to the routines and to return
  information to the user. The indices of \ct{xstore} which the user may access
  have defined names, e.\,g.\ \ct{xstore[BASICLU\_STATUS]} holds the status
  code. \ct{istore} need not be accessed by the user.
\item{\ct{Li}, \ct{Lx}, \ct{Ui}, \ct{Ux}, \ct{Wi}, \ct{Wx}} are arrays whose
  required size is not known in advance. Their size must be given by the user
  as parameters (see below) and BASICLU will request reallocation if the size is
  insufficient. These arrays need not be accessed by the user.
\end{description}

\newpage
\subsection{basiclu\_initialize}
{\footnotesize
\input{basiclu_initialize}
}

\newpage
\subsection{basiclu\_factorize}
{\footnotesize
\input{basiclu_factorize}
}

\newpage
\subsection{basiclu\_get\_factors}
{\footnotesize
\input{basiclu_get_factors}
}

\newpage
\subsection{basiclu\_solve\_dense}
{\footnotesize
\input{basiclu_solve_dense}
}

\newpage
\subsection{basiclu\_solve\_sparse}
{\footnotesize
\input{basiclu_solve_sparse}
}

\newpage
\subsection{basiclu\_solve\_for\_update}
{\footnotesize
\input{basiclu_solve_for_update}
}

\newpage
\subsection{basiclu\_update}
{\footnotesize
\input{basiclu_update}
}
\newpage

%-------------------------------------------------------------------------------
\section{High level C interface}
%-------------------------------------------------------------------------------
The high level C interface consists of wrapper functions around the low level
interface which do memory allocation. They maintain the arrays used by the low
level interface inside a \ct{struct basiclu\_object}. To use the high level C
interface, user code must include \ct{basiclu.h}. Defined constants start with
\ct{BASICLU\_} and function names start with \ct{basiclu\_obj\_}.

\newpage
\subsection{basiclu\_object}
{\footnotesize
\input{basiclu_object}
}

\newpage
\subsection{basiclu\_obj\_initialize}
{\footnotesize
\input{basiclu_obj_initialize}
}

\newpage
\subsection{basiclu\_obj\_get\_dim}
{\footnotesize
\input{basiclu_obj_get_dim}
}

\newpage
\subsection{basiclu\_obj\_factorize}
{\footnotesize
\input{basiclu_obj_factorize}
}

\newpage
\subsection{basiclu\_obj\_get\_factors}
{\footnotesize
\input{basiclu_obj_get_factors}
}

\newpage
\subsection{basiclu\_obj\_solve\_dense}
{\footnotesize
\input{basiclu_obj_solve_dense}
}

\newpage
\subsection{basiclu\_obj\_solve\_sparse}
{\footnotesize
\input{basiclu_obj_solve_sparse}
}

\newpage
\subsection{basiclu\_obj\_solve\_for\_update}
{\footnotesize
\input{basiclu_obj_solve_for_update}
}

\newpage
\subsection{basiclu\_obj\_update}
{\footnotesize
\input{basiclu_obj_update}
}

\newpage
\subsection{basiclu\_obj\_free}
{\footnotesize
\input{basiclu_obj_free}
}

\newpage
\subsection{basiclu\_obj\_maxvolume}
{\footnotesize
\input{basiclu_obj_maxvolume}
}
\newpage
 
%-------------------------------------------------------------------------------
\section{Julia interface}
%-------------------------------------------------------------------------------
BASICLU can be used from the Julia programming language. The easiest way is to
install the artifact \ct{basiclu\_jll}, which provides a precompiled library.
Alternatively the code can be compiled from source as described in
Section~\ref{sec:install}. In this case ensure that \ct{int64\_t} is used as
integer type (this is the default). To use the locally compiled library,
environment variable \ct{JULIA\_BASICLU\_LIBRARY\_PATH} must point to the
\ct{lib/} directory.

The following is an example for a Julia program using BASICLU. See also the
documentation of the module functions and \ct{Julia/test.jl}.
{\footnotesize
\begin{verbatim}
include("BASICLU/Julia/basiclu.jl")
m = 1000
obj = basiclu.basiclu_object(m)
B = sprand(m,m,5e-3) + I                     # get a sparse matrix
basiclu.factorize(obj, B)
rhs = randn(m)                               # get a right-hand side
lhs = basiclu.solve(obj, rhs, 'N')
res = norm(B*lhs-rhs,Inf)                    # compute residual
col = sparsevec([1], [1.0], m)               # vector to be inserted into B
lhs = basiclu.solve_for_update(obj, col, getsol=true)
vmax, j = findmax(abs.(lhs))
piv = lhs[j]
basiclu.solve_for_update(obj, j)            # prepare to replace column j of B
piverr = basiclu.update(obj, piv)
lhs = basiclu.solve(obj, rhs, 'N')
B[:,j] = col
res = norm(B*lhs-rhs,Inf)
\end{verbatim}
}
\end{document}
