\section{Matrix-Free Capabilities \label{matrix.free}}
Version 2.1 contains a matrix-free capability.  However, 
this capability is still undergoing some changes. 
In this document we describe the \Az{} interface
and give concrete examples with user-defined matrix-vector
products and user-defined preconditioners.
At present, only the `C' interface
has been completed. A Fortran interface will follow.

\subsection{{ AZ\_iterate}\label{interface}}

To use \Az{}'s solvers, a subroutine driver entitled {\it AZ\_iterate}
must be invoked. For those familiar with \Az{}{\bf 1.1}, this subroutine
replaces {\it AZ\_solve}. It should be noted that:
\begin{itemize}
\item {\it AZ\_solve} may still be used (when matrix-free is not needed).
%\item matrix-free capabilities can only be accessed via {\it AZ\_iterate}.
%\item {\it AZ\_iterate} is a superset of {\it AZ\_solve}. 
%That is, all the capabilities within {\it AZ\_solve} are available 
%via {\it AZ\_iterate}.
%\item {\it AZ\_iterate} will eventually replace {\it AZ\_solve}. 
%That is,
%      in the future {\it AZ\_solve} will no longer be supported.
\item The interface to {\it AZ\_iterate} will probably change a bit to
      incorporate new developments (including the integration of \Az{}
      with eigenvalue solvers and multilevel solvers).
\end{itemize}
There are three conceptual differences between {\it AZ\_iterate} and 
{\it AZ\_solve}:
\begin{itemize}
\item the user's matrix is more generalized and is now passed through a structure,
\item user-supplied preconditioning can be used,
\item {\bf two different matrices} can be supplied: one to solve
      and one to use within preconditioning. For example, \Az{}
      can solve equations $A x = f $ by applying an incomplete 
      factorization to a matrix $B$ which is 
      a sparse approximation to $A$.
\end{itemize}
The syntax for {\it AZ\_iterate} is given below.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
\protobox{void AZ\_iterate(double *{\it x\/}, double *{\it b\/}, int
*{\it options\/}, double *{\it params\/}, double *{\it status\/}, \\
$\hphantom{void AZ_iterate(}$ int *{\it proc\_config\/}, AZ\_MATRIX
*{\it Amat\/},
AZ\_PRECOND *{\it prec\/}, \\
$\hphantom{void AZ_iterate(}$ struct AZ\_SCALING *{\it scaling\/})}

\vspace{2em}
{\flushleft{\bf Parameters} \hrulefill}
\vspace{1em}

\optionbox{x, b, options, params, \\
           status, proc\_config}{These parameters are identical to those
           in {\it AZ\_solve} and are described in Section \ref{subroutines}.}

\optionbox{Amat}{On input, a structure representing the matrix to be
           solved (described below).}

\optionbox{prec}{On input, either NULL (implying \Az{}'s preconditioners
           are applied to {\it Amat}) or a structure indicating 
           the preconditioning routine and matrix to which preconditioning
           is applied (described below).}

\optionbox{scaling}{Currently not used.}

\vskip .1in
To complete the discussion, we must describe
how $Amat$ and $prec$ are created and set.
\subsection{Matrix-vector product examples.} 
The following examples use a variety of functions: 
{\it AZ\_set\_MSR()}, {\it AZ\_set\_VBR()}, etc.
%{\it AZ\_set\_MATFREE()},
%{\it AZ\_matrix\_create()}, 
%{\it AZ\_matrix\_destroy()},
%and 
%{\it AZ\_get\_matvec\_data ()}.
These functions are more fully described in Section \ref{subroutines}.
\vskip .1in
\underline{Example 1: DMSR or DVBR matrices}
\vskip .1in
\noindent
{\it AZ\_solve}() users with DMSR matrices can convert to {\it AZ\_iterate}()
by replacing 
\begin{verbatim}
   AZ_solve(x, b, options, params, indx, bindx, rpntr, cpntr, bpntr, 
            val, data_org, status, proc_config);
\end{verbatim}
with
\begin{verbatim}
   AZ_MATRIX *Amat;
      .
      .
   Amat = AZ_matrix_create(data_org[AZ_N_internal] +
                           data_org[AZ_N_border]);
   AZ_set_MSR(Amat, bindx, val, data_org, 0, NULL, AZ_LOCAL);
   AZ_iterate(x, b, options, params, status, proc_config, Amat, NULL, NULL);
   AZ_matrix_destroy(&Amat);
\end{verbatim}
Users with DVBR matrices  would replace {\it AZ\_set\_MSR()} by
\begin{verbatim}
    AZ_set_VBR(Amat, rpntr, cpntr, bpntr, indx, bindx,
               val, data_org, 0, NULL, AZ_LOCAL);
\end{verbatim}
\vskip .3in
\underline{Example 2: user-supplied matrix-vector product}
\vskip .1in
\noindent
This case is almost identically to the DMSR or DVBR examples
above except that {\it AZ\_set\_MATFREE} 
(as opposed to {\it AZ\_set\_MSR} or {\it AZ\_set\_VBR})
is used to associated
the user-defined matrix-vector product with the matrix.
\begin{verbatim}
   AZ_MATRIX *Amat;
      .
      .
   Amat = AZ_matrix_create(N_equations);
   AZ_set_MATFREE(Amat, my_data, my_matvec);
   AZ_iterate(x, b, options, params, status, proc_config, Amat, NULL, NULL);
   AZ_matrix_destroy(&Amat);
\end{verbatim}
{\tt N\_equations} is the number of matrix rows implicitly
kept on this processor (i.e. the length of the vector 
$y_{\mbox{\scriptsize local}}$ after performing 
$ y_{\mbox{\scriptsize local}} =  A_{\mbox{\scriptsize local}} 
x_{\mbox{\scriptsize local}}$). 
{\tt my\_data} is a user-defined data pointer that will be passed to
the user-defined matrix-vector product function {\tt my\_matvec}.
{\tt my\_matvec} should have the following proto-type:
\begin{verbatim}
void my_matvec(double *p, double *ap, AZ_MATRIX *Amat, int proc_config[])
\end{verbatim}
where

\optionbox{p}{On input, {\it p\/} is a vector containing local vector
              components for this processor. NOTE: \Az{}'s internal
              matrix-vector multiplies require additional space 
              (see {\it AZ\_solve}() description in Section \ref{subroutines}).}
\optionbox{ap}{On output, {\it ap\/} is set to $ (Amat)*p $.}
\optionbox{Amat}{On input, structure representing matrix 
                       used in matrix-vector multiplication.}
\optionbox{proc\_config}{On input, {\it proc\_config}[{\sf AZ\_node}] is 
                       set via the command {\it AZ\_set\_proc\_config }. }
Whenever the user-defined data pointer, {\it my\_data}, is needed inside 
{\it my\_matvec}(), it can be obtained via the function 
{\it AZ\_get\_matvec\_data (Amat)}.

\subsection{Preconditioning examples.} 
The following examples use: 
{\it AZ\_precond\_create()}, 
and 
{\it AZ\_precond\_destroy()}.
These functions are more fully described in Section \ref{subroutines}.
\vskip .1in
\underline{Example 1: Standard \Az{} preconditioning}
\vskip .1in
\noindent
Standard \Az{} preconditioning can be invoked 
by creating a preconditioner,
\begin{verbatim}
   AZ_PRECOND *prec;
      .
      .
   prec = AZ_precond_create(Amat, AZ_precondition, NULL);,
\end{verbatim}
passing it to {\it AZ\_iterate}(),
\begin{verbatim}
   AZ_iterate(x, b, options, params, status, proc_config, Amat, prec, NULL);,
\end{verbatim}
and finally clearing it with
\begin{verbatim}
   AZ_precond_destroy(&prec);
\end{verbatim}
\vskip .3in
\underline{Example 2: Standard \Az{} preconditioning applied to $B$}
\vskip .1in
\noindent
\Az{}'s preconditioners can be applied to a matrix, $B$, which is
different from the matrix being solved. In this case, the following
might be used:
\begin{verbatim}
   AZ_PRECOND *prec;
   AZ_MATRIX  *Amat, *Bmat;
      .
      .
   N_equations = data_org[AZ_N_internal]+data_org[AZ_N_border];
   Amat = AZ_matrix_create(N_equations);
   AZ_set_MSR(Amat, bindx, val, data_org, 0, NULL, AZ_LOCAL);
   Bmat = AZ_matrix_create(N_equations);
   AZ_set_MSR(Bmat, bindx2, val2, data_org2, 0, NULL, AZ_LOCAL);
   prec = AZ_precond_create(Bmat, AZ_precondition, NULL);
   AZ_iterate(x, b, options, params, status, proc_config, Amat, prec, NULL);
   AZ_matrix_destroy(&Amat);
   AZ_matrix_destroy(&Bmat);
   AZ_precond_destroy(&prec);
\end{verbatim}
\vskip .3in
\underline{Example 3: user-supplied preconditioner}
User-supplied preconditioning requires that the user's function pointer
and data pointer be given to {\sf AZ\_precond\_create()}.
For example,
\begin{verbatim}
   AZ_PRECOND *prec;
   AZ_MATRIX  *Amat;
      .
      .
   N_equations = data_org[AZ_N_internal]+data_org[AZ_N_border];
   Amat = AZ_matrix_create(N_equations);
   AZ_set_MSR(Amat, bindx, val, data_org, 0, NULL, AZ_LOCAL);
   prec = AZ_precond_create(Amat, my_preconditioner, my_data);
   AZ_iterate(x, b, options, params, status, proc_config, Amat, prec, NULL);
   AZ_matrix_destroy(&Amat);
   AZ_precond_destroy(&prec);
\end{verbatim}
{\tt my\_data} is a user-defined data pointer that will be passed to
the user-defined preconditioner function {\tt my\_preconditioner}.
{\tt my\_preconditioner} should have the following proto-type:
\begin{verbatim}
void my_preconditioner(double *z, int *options, int *proc_config, 
                       double *params, AZ_MATRIX *Amat, 
                       AZ_PRECOND *prec)
\end{verbatim}
where
\optionbox{z}{On input, {\it z\/} is a vector containing all the local vector
              components for this processor. On output, {\it z\/} is the
              preconditioned vector (local components).}

\optionbox{options, proc\_config\\
params, Amat, prec }{Same as those given to {\it AZ\_iterate}.}


\subsection{\Az{} preconditioning with user-defined matrices.} 
In general, \Az{} needs to know something about the matrix
in order to apply a preconditioner (see Table 1).
\vskip .1in
\noindent
%\begin{table}[h]
\begin{tabular}{|ll|}
\hline 
Preconditioner    & needed matrix information \\[9pt] \hline
Jacobi            & matrix diagonal \\
least squares  polynomial   & infinity norm of matrix \\
Neumann polynomial & infinity norm of matrix \\
incomplete  factorizations & algebraic preconditioners are used for the  subdomain\\
                  & solvers. These algebraic preconditioners need \\
                  & matrix entries.  \\
\hline 
\end{tabular}
\begin{center}
Table 1: {\it Data requirements for various preconditioners.}
\end{center}
\vskip .1in
%\caption{Data requirements of various preconditioners.\label{requirements}}
%\end{table}
For the polynomial preconditioners, it is possible to give \Az{}
the infinity norm via the command {\sf AZ\_set\_MATFREE\_matrix\_norm()}.
For Jacobi preconditioning it is often possible to give the 
matrix diagonal in a separate DMSR matrix. However, for most of the
other preconditioners, it is necessary to give all the matrix 
information.  The current \Az{} contains an experimental `getrow'
facility which allows this to be done. This `getrow' is demonstrated
in the example program \verb'az_mat_free_main.c' but is not officially
released as it is still undergoing changes.

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

%\vspace{2em}
%
%\section{Compiling and Linking\label{comp_link}}
%
%The krylov solver library {\bf Aztec} uses code from a few publicly
%available linear algebra packages.  These packages are 1) the basic
%linear algebra subroutine library - BLAS  2) the linear algebra
%package - LAPACK and 3) a sparse direct lu solver Y12M. These packages
%can be obtained form netlib as described below.
%
%The following packages are needed by {\bf Aztec}:
%\begin{itemize}
%\item Y12M (used for LU factorizations)
%\item LAPACK routines
%\item BLAS   routines
%\end{itemize}
%These routines can be obtained via netlib.
%Send email to netlib@ornl.gov with the following information
%in the message:
%\vskip .5in
%\begin{verbatim}
%send help
%send index for y12m
%send index for lapack
%send index for blas
%\end{verbatim}
%\vskip .5in
%
%Current information on compiling and linking {\bf Aztec}
%for supported machines can be found in the file \verb'README'
%in the source code distribution directory.
%
%To obtain the {\bf Aztec} distribution send an email request to
%Ray S. Tuminaro (tuminaro@cs.sandia.gov).


%\newpage
%\bibliographystyle{plain}
%\bibliography{aztec_guide}
%
%
%\end{document}
